home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1995 #5 & #6 / Amiga Plus CD - 1995 - No. 5 and 6.iso / tex / macros / distribs / doc / docstrip.doc (.txt) < prev    next >
LaTeX Document  |  1992-09-07  |  112KB  |  2,711 lines

  1. % \iffalse meta-comment
  2. % Copyright (C) 1989-1992 by Frank Mittelbach.  All rights reserved.
  3. % This file is part of the doc package.
  4. % IMPORTANT NOTICE:
  5. % You are not allowed to change this file.  You may however copy
  6. % this file to a file with a different name and then change the
  7. % copy if you obey the restrictions on file changes described in
  8. % readme.mz.
  9. % You are NOT ALLOWED to distribute this file alone.  You are NOT
  10. % ALLOWED to take money for the distribution or use of this file
  11. % (or a changed version) except for a nominal charge for copying
  12. % etc.
  13. % You are allowed to distribute this file under the condition that
  14. % it is distributed together with all files mentioned in
  15. % readme.mz0.
  16. % If you receive only some of these files from someone, complain!
  17. % However, if these files are distributed by established suppliers
  18. % as part of a complete TeX distribution, and the structure of the
  19. % distribution would make it difficult to distribute the whole set
  20. % of files, *those parties* are allowed to distribute only some of
  21. % the files provided that it is made clear that the user will get
  22. % a complete distribution-set upon request to that supplier (not
  23. % me).  Notice that this permission is not granted to the end
  24. % user.
  25. % For error reports in case of UNCHANGED versions see readme.mz
  26. % \fi
  27. \def\filename{docstrip.doc}
  28. \def\fileversion{2.0r}
  29. \def\filedate{92/08/17}
  30. \def\docdate {92/08/17}
  31. % \CheckSum{1421}
  32. %% \CharacterTable
  33. %%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
  34. %%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
  35. %%   Digits        \0\1\2\3\4\5\6\7\8\9
  36. %%   Exclamation   \!     Double quote  \"     Hash (number) \#
  37. %%   Dollar        \$     Percent       \%     Ampersand     \&
  38. %%   Acute accent  \'     Left paren    \(     Right paren   \)
  39. %%   Asterisk      \*     Plus          \+     Comma         \,
  40. %%   Minus         \-     Point         \.     Solidus       \/
  41. %%   Colon         \:     Semicolon     \;     Less than     \<
  42. %%   Equals        \=     Greater than  \>     Question mark \?
  43. %%   Commercial at \@     Left bracket  \[     Backslash     \\
  44. %%   Right bracket \]     Circumflex    \^     Underscore    \_
  45. %%   Grave accent  \`     Left brace    \{     Vertical bar  \|
  46. %%   Right brace   \}     Tilde         \~}
  47. %\iffalse
  48. %% The docstrip program for use with TeX.
  49. %% Copyright (C) 1989-1991 Frank Mittelbach
  50. %% Copyright (C) 1992 Johannes Braams, Denys Duchier, Frank Mittelbach
  51. %% All rights are reserved.
  52. % Please report errors to: see readme
  53. % \fi
  54. % \changes{2.0q}{92/07/01}{Changed all dates to yy/mm/dd for better
  55. %                          sorting}
  56. % \changes{2.0b}{91/05/29}{Added bugfix from Denys}
  57. % \changes{2.0c}{91/05/29}{Allow almost all characters in guard (DD)}
  58. % \changes{2.0d}{91/05/31}{Started merging in some of Franks code}
  59. % \changes{2.0j}{92/03/05}{Wrote introduction}
  60. % \changes{2.0m}{92/04/21}{Renamed all macros that deal with the parsing
  61. %                          of boolean expressions}
  62. % \changes{2.0m}{92/04/25}{Removed dependency from ltugboat,
  63. %                          incorporated driver file into source.}
  64. % \changes{2.0m}{92/04/25}{Added some missing percents; corrected some
  65. %                          typos}
  66. % \changes{2.0m-DL}{92/05/08}{Various small corrections to English and 
  67. %                           typos}
  68. % \DoNotIndex{\#,\$,\%,\&,\@,\\,\{,\},\^,\_,\~,\ }
  69. % \DoNotIndex{\@ne}
  70. % \DoNotIndex{\advance,\begingroup,\catcode,\closein,\closeout}
  71. % \DoNotIndex{\day,\def,\edef,\else,\empty,\endgroup,\errmessage}
  72. % \DoNotIndex{\expandafter,\fi,\futurelet,\gdef,\global,\if,\ifeof}
  73. % \DoNotIndex{\ifx,\immediate,\let,\loop,\m@ne,\message,\month}
  74. % \DoNotIndex{\newcount}
  75. % \DoNotIndex{\newif,\newlinechar,\newread,\newtoks,\newwrite}
  76. % \DoNotIndex{\noexpand,\openin,\openout,\par,\read,\relax,\repeat}
  77. % \DoNotIndex{\space,\the,\undefined,\write,\xdef,\year,\z@}
  78. % ^^A some definitions for this documentation
  79. % \newcommand{\ds}{{\sf DocStrip}} ^^A maybe?
  80. % \newcommand{\bsl}{\protect\bslash}
  81. % \newcommand{\note}[1]{\marginpar{{\bf #1}}}
  82. % \newcommand{\netaddress}[1]{{\tt #1}}
  83. % ^^A override the default in doc.sty
  84. % \makeatletter
  85. % \renewenvironment{theglossary}{%
  86. %    \glossary@prologue%
  87. %    \GlossaryParms \let\item\@idxitem \ignorespaces}%
  88. %   {}
  89. % \makeatother
  90. % ^^A compatibility with OFSS
  91. % \ifx\undefined\selectfont \newcommand{\fontshape}[1]{} \fi
  92. % \MakeShortVerb\|
  93. % \title{The \ds{} program%
  94. %         \thanks{This file has version number \fileversion,
  95. %                 last revised \filedate,
  96. %                 documentation dated \docdate.}}
  97. % \author{%
  98. %   Frank Mittelbach \\
  99. %   \netaddress{Mittelbach@mzdmza.zdv.uni-mainz.de}
  100. %  \and
  101. %   Denys Duchier \\
  102. %   \netaddress{duchier-denys@cs.yale.edu}
  103. %  \and
  104. %   Johannes Braams \\
  105. %   PTT Research Neher Laboratories\\
  106. %          P.O. Box 421\\
  107. %          2260 AK Leidschendam\\
  108. %   \netaddress{JL\_Braams@research.ptt.nl}}
  109. % \date{Printed \today}
  110. % \maketitle
  111. % \begin{abstract}
  112. %    This document describes the implementation of the \ds{} program.
  113. %    The original version of this program was developed by Frank
  114. %    Mittelbach to accompany his {\tt doc.sty} which enables literate
  115. %    programming in \LaTeX\@. Denys Duchier rewrote it to run either
  116. %    with \TeX\ or of \LaTeX, and to allow full boolean expressions in
  117. %    conditional guards instead of just comma-separated lists.
  118. %    Johannes Braams re-united the two implementations, documented and
  119. %    debugged the code.
  120. % \end{abstract}
  121. % \section{Introduction}
  122. %  \subsection{Why the \ds{} program?}
  123. %    When Frank Mittelbach created the {\tt doc} option, he invented a
  124. %    way to combine \TeX\ code and its documentation. From then on it
  125. %    was more or less possible to do literate programming in \TeX.
  126. %    This way of writing \TeX\ programs obviously has great
  127. %    advantages, especially when the program becomes larger than a
  128. %    couple of macros.  There is one drawback however, and that is
  129. %    that such programs may take longer than expected to run because
  130. %    \TeX\ is an interpreter and has to decide for each line of the
  131. %    program file what it has to do with it. Therefore, \TeX\ programs
  132. %    may be speeded up by removing all comments from them.
  133. %    By removing the comments from a \TeX\ program a new problem is
  134. %    introduced. We now have two versions of the program and both of
  135. %    them {\em have\/} to be maintained. Therefore it would be nice to
  136. %    have a possibility to remove the comments automatically, instead
  137. %    of doing it by hand. So we need a program to remove comments from
  138. %    \TeX\ programs. This could be programmed in any high level
  139. %    language, but maybe not everybody has the right compiler to
  140. %    compile the program.  Everybody who wants to remove comments from
  141. %    \TeX\ programs has \TeX\@.  Therefore the \ds{} program is
  142. %    implemented entirely in \TeX.
  143. % \subsection{Functions of the \ds{} program} 
  144. %    Having created the \ds{} program to remove comment lines from
  145. %    \TeX\ programs\footnote{Note that only comment lines, that is
  146. %    lines that start with a single {\tt\%} character, are removed;
  147. %    all other comments st in the code.} it became feasible to do more
  148. %    than just strip comments.\\ Wouldn't it be nice to have a way to
  149. %    include parts of the code only when some condition is set true?
  150. %    Wouldn't it be as nice to have the possibility to split the
  151. %    source of a \TeX\ program into several smaller files and combine
  152. %    them later into one `executable'?\\ Both these wishes have been
  153. %    implemented in the \ds{} program.
  154. %  \subsection{How to use the \ds{} program}
  155. %    A number of ways exist to use the \ds{} program:
  156. %    \begin{enumerate}
  157. %    \item The easiest way is to instruct \TeX\ to read the file
  158. %        {\tt docstrip.tex} and to see what happens. \TeX\ will ask
  159. %        you a few questions about the file you would like to be
  160. %        processed. When you have answered these questions it does
  161. %        its job and strips the comments from your \TeX\ code.
  162. %    \item When you would like to be able to process more than one
  163. %        file with one command, or you would like to add a couple of
  164. %        lines to the beginning (or end) of the stripped file you
  165. %        can write a `batch file' for \ds{}. The default
  166. %        name for such a file is {\tt docstrip.cmd}. When a file by
  167. %        that name  exists in your current directory when you instruct
  168. %        \TeX\ to read {\tt docstrip.tex} it will verify (by asking you)
  169. %        that you want
  170. %        to use {\em that\/} file and if so, will process the commands
  171. %        in it.
  172. %        You do not need to use the default name, however. You can
  173. %        give a batch file any name you like such as, say, {\tt
  174. %        foo.bar} and then r \TeX\ by using a command such as:
  175. %    \begin{verbatim}
  176. %    TeX \def\batchfile{foo.bar}\input docstrip
  177. %    \end{verbatim}
  178. % \item You may use yet another way that is only slightly different
  179. %        from the previous method. You can write a batch file in such
  180. %        a way that it can be directly processed by \TeX{}. This
  181. %        allows you to set up a distribution where you can instruct
  182. %        the user to simply run
  183. %      \begin{quote}
  184. %        {\tt TEX} \meta{batch file}
  185. %      \end{quote}
  186. %        to generate the executable versions of your files from the
  187. %        distribution sources. All distributions from Mainz are set up
  188. %        in this way (also this one); look, for example, at the
  189. %        installation file for this distribution.  To produce such a
  190. %        batch file include a statement in your `batch file' that
  191. %        instructs \TeX\ to read {\tt docstrip.tex}. You should then
  192. %        also define \verb=\batchfile= to contain the name of that
  193. %        `batch file'. The beginning of such a file would look like:
  194. %    \begin{verbatim}
  195. %    \def\batchfile{install.me}
  196. %    \input docstrip
  197. %    ...
  198. %    \end{verbatim}
  199. %    \end{enumerate}
  200. % \section{The user interface}
  201. % \subsection{The main program}
  202. % \DescribeMacro{\processbatchFile} The `main program' starts with
  203. %    trying to process a batch file, this is accomplished by calling
  204. %    the macro |\processbatchFile|. It counts the number of batch
  205. %    files it processes, so that when the number of files processed is
  206. %    still zero after the call to |\processbatchFile| appropriate
  207. %    action can be taken.
  208. % \DescribeMacro{\interactive} When no batch files have been processed
  209. %    the macro |\interactive| is called. It prompts the user for
  210. %    information. First the extensions of the input and output files
  211. %    is determined. Then a question about optional code is asked and
  212. %    finally the user can give a list of files that have to be
  213. %    processed.
  214. % \DescribeMacro{\ReportTotals} When the {\tt stats} option is
  215. %    included in the \ds{}-program it keeps a record of the number of
  216. %    files and lines that are processed.  Also the number of comments
  217. %    removed and passed as well as the number of code lines that were
  218. %    passed to the output are accounted. The macro |\ReportTotals|
  219. %    shows a summary of this information.
  220. % \subsection{Batchfile commands}
  221. %    The commands described in this section are available to build a
  222. %    batch file.
  223. % \DescribeMacro{\showprogress}
  224. % \DescribeMacro{\keepsilent}
  225. %    When the option {\tt stats} is included in \ds{} it can
  226. %    write message to the terminal as each line of the input file(s) is
  227. %    processed. This message consists of a single character, indicating
  228. %    what the program does with that particular line. We use the
  229. %    following characters:
  230. %    \begin{itemize}
  231. % \item[{\tt \%}] Whenever an input line is removed a
  232. %        {\tt\%}-character is written to the terminal.
  233. % \item[{\tt .}] Whenever a code line is passed on to the output file
  234. %        a {\tt .}-character is written on the terminal.
  235. % \item[{\tt /}] When a number of empty lines appear in a row in the
  236. %        input file, at most one of them is retained. The \ds{}
  237. %        program signals the removal of an empty line with the {\tt
  238. %        /}-character.
  239. % \item[{\tt <}] When a `guard line' is found in the input and it
  240. %        starts a block of optionally included code, this is signalled
  241. %        on the terminal by showing the {\tt <}-character, together
  242. %        with the boolean expression of the guard.
  243. % \item[{\tt >}] The end of a conditionally included block of code is
  244. %        indicated by showing the {\tt >}-character.
  245. %    \end{itemize}
  246. %    This feature is turned on by default when the option {\tt stats} is
  247. %    included, otherwise it is turned of. The feature can be toggled
  248. %    with the commands |\showprogress| and |\keepsilent|
  249. % \DescribeMacro{\preamble}
  250. % \DescribeMacro{\endpreamble}
  251. % \DescribeMacro{\postamble}
  252. % \DescribeMacro{\endpostamble}
  253. %    It is possible to add a number of lines to the output of
  254. %    the \ds{} program. The information you want to add to the
  255. %    start of the output file should be listed between the |\preamble|
  256. %    and |\endpreamble| commands; the lines you want to add to the end
  257. %    of the output file should be listed between the |\postamble| and
  258. %    |\endpostamble| commands. Everything that \ds{} finds
  259. %    for both the pre- and postamble it writes to the output file, but
  260. %    preceded with two \%-characters. If you include a |^^M| character
  261. %    in one of these lines, everything that follows it on the same line
  262. %    is written to a new line in the output file.
  263. %    This `feature' can be used to add a |\typeout| or |\message| to the
  264. %    the stripped file.
  265. % \DescribeMacro{\generateFile}
  266. %    The main reason for constructing a \ds{} command file is that
  267. %    one doesn't want to type in the instructions for \TeX\ each time
  268. %    a macro file is stripped of its comments. The macro |\generateFile|
  269. %    is used to tell \TeX\ what to do. Its syntax is:
  270. %    \begin{quote}
  271. %    |\generateFile{|\meta{output}|}{|\meta{ask}|}{|[|\from{|^^A
  272. %                    \meta{input}|}{|\meta{optionlist}|}|]*|}|
  273. %    \end{quote}
  274. %    The \meta{output} and \meta{input} are normal file specifications
  275. %    as are apropriate for your computer system. The \meta{optionlist}
  276. %    is a comma separated list of `options' that specify which
  277. %    optional code fragments in \meta{input} should be included in
  278. %    \meta{output}.  With \meta{ask} you can instruct \TeX\ to either
  279. %    silently overwrite a previously existing file (|f|) or to issue a
  280. %    warning and ask you if it should overwrite the existing file
  281. %    (|t|).
  282. %    It is possible to specify multiple input files, each with its own
  283. %    \meta{optionlist}. This is indicated by the notation [\ldots]*.
  284. % \DescribeMacro{\include}
  285. % \DescribeMacro{\processFile}
  286. %    The earlier version of the \ds{} program supported a
  287. %    different kind of command to tell \TeX\ what to do. This command
  288. %    is less powerful than |\generateFile|; it can be used when
  289. %    \meta{output} is created from one \meta{input}. The syntax is:
  290. %    \begin{quote}
  291. %    |\include{|\meta{optionlist}|}|
  292. %    |\processFile{|\meta{name}|}{|\meta{inext}^^A
  293. %                              |}{|\meta{outext}^^A
  294. %                              |}{|\meta{ask}|}|
  295. %    \end{quote}
  296. %    This command is based on environments where filenames are
  297. %    constructed of two parts, the name and the extension, separated
  298. %    with a dot. The syntax of this command assumes that the
  299. %    \meta{input} and \meta{output} share the same name and only
  300. %    differ in their extension. This command is retained to be
  301. %    backwards compatible with the older version of \ds{}, but its use
  302. %    is not encouraged.
  303. % \DescribeMacro{\input}
  304. % \DescribeMacro{\batchinput}
  305. %    The batch file commands can be put into several batch files which
  306. %    are then executed from a master batch file. This is, for example,
  307. %    useful if a distribution consists of several distinct parts. You
  308. %    can then write individual batch files for every part and in
  309. %    addition a master file that simply calls the batch files for the
  310. %    parts.  For this, call the individual batch files from the master
  311. %    file with the command |\batchinput|.  Don't use |\input| for this
  312. %    purpose, this command should be used only for calling the \ds{}
  313. %    program as explained above and is ignored when used for any other
  314. %    purpose.
  315. % \section{Conditional inclusion of code}
  316. %    When you use the \ds{} program to strip comments out of
  317. %    \TeX\ macro files you have the possibility to make more than one
  318. %    stripped macro file from one documented file. This is achieved by
  319. %    the support for optional code. The optional code is marked
  320. %    in the documented file with a `guard'.
  321. %    A guard is a boolean expression that is enclosed in |<| and |>|.
  322. %    It also {\em has\/} to follow the |%| at the beginning of the line.
  323. %    For example:
  324. %\begin{verbatim}
  325. %    ...
  326. %    %<bool>\TeX code
  327. %    ...
  328. %\end{verbatim}
  329. %    In this example the line of code will be included in \meta{output}
  330. %    if the option {\tt bool} is present in the \meta{optionlist} of
  331. %    the |\generateFile| command.
  332. %    The syntax for the boolean expressions is:
  333. %\DeleteShortVerb\|
  334. %    \begin{tabular}{lcl}
  335. %    \meta{Expression} & $::=$ & \meta{Primary}
  336. %                            [\{{\tt|}, {\tt,}\} \meta{Primary}]*\\
  337. %    \meta{Primary}    & $::=$ & 
  338. %                        \meta{Secondary} [{\tt\&} \meta{Secondary}]*\\
  339. %    \meta{Secondary}  & $::=$ & 
  340. %                        \meta{Terminal} $|$ {\tt!}\meta{Secondary}
  341. %                        $|$ {\tt(}\meta{Expression}{\tt)}\\
  342. %    \end{tabular}
  343. %    The {\tt|} stands for disjunction, the {\tt\&} stands for
  344. %    conjunction and the {\tt!}\ stands for negation. The
  345. %    \meta{Terminal} is any sequence of letters and evaluates to
  346. %    \meta{true} iff\footnote{iff stands for `if and only if'} it
  347. %    occurs in the list of options that have to be included.
  348. %\MakeShortVerb\|
  349. %    Two kinds of optional code are supported: one can either have
  350. %    optional code that `fits' on one line of text, like the example
  351. %    above, or one can have blocks of optional code.
  352. %    To distinguish both kinds of optional code the `guard modifier'
  353. %    has been introduced. The `guard modifier' is one character that
  354. %    immediately follows the |<| of the guard. It can be either |*|
  355. %    for the beginning of a block of code, or |/| for the end of
  356. %    a block of code\footnote{To be compatible with the earlier version
  357. %    of \ds{} also {\tt +} and {\tt -} are supported as `guard
  358. %    modifiers'.  However, there is an incompatibility with the
  359. %    earlier version since a line with a {\tt +}-modified guard is not
  360. %    included inside a block with a guard that evaluates to false, in
  361. %    contrast to the previous behaviour.}.  The beginning and ending
  362. %    guards for a block of code have to be on a line by themselves.
  363. %    When a block of code is {\em not\/} included, any guards that occur
  364. %    within that block are {\em not\/} evaluated.
  365. %\StopEventually{%
  366. %^^A \section{Conclusion}
  367. %  \PrintIndex
  368. %  \PrintChanges
  369. %^^A \makesignature
  370. % \section{The implementation}
  371. % \subsection{Declarations and initializations}
  372. %    In order to be able to include the {\tt @}-sign in control
  373. %    sequences its category code is changed to \meta{letter}.  The
  374. %    `program' guard here allows most of the code to be excluded when
  375. %    extracting the driver file.
  376. %    \begin{macrocode}
  377. %<*program>
  378. \catcode`\@=11
  379. %    \end{macrocode}
  380. %    When we want to write multiple lines to the terminal with one
  381. %    statement, we need a character that tells \TeX\ to break the lines.
  382. %    We use \verb=^^J= for this purpose.
  383. %    \begin{macrocode}
  384. \newlinechar=`\^^J
  385. %    \end{macrocode}
  386. % \subsubsection{Token registers}
  387. % \begin{macro}{\TerminalString}
  388. % \changes{2.0m}{92/04/22}{Renamed from {\tt\bsl boolToks}}
  389. %    A token register is allocated that will be used to accumulate
  390. %    the tokens that make up a \meta{Terminal} in the process
  391. %    of scanning guards.
  392. %    \begin{macrocode}
  393. \newtoks\TerminalString
  394. %    \end{macrocode}
  395. % \end{macro}
  396. % \subsubsection{Switches}
  397. % \begin{macro}{\ifOff}
  398. % \begin{macro}{\ifGenerate}
  399. %    The switch \verb=\ifOff= will be used to signal if code lines
  400. %    have to be included in the output.  The program will check if a
  401. %    file of the same name as the file it would be creating already
  402. %    exists. The switch \verb=\ifGenerate= is used to indicate if the
  403. %    stripped file has to be generated.
  404. %    \begin{macrocode}
  405. \newif\ifOff
  406. \newif\ifGenerate
  407. %    \end{macrocode}
  408. % \end{macro}
  409. % \end{macro}
  410. % \begin{macro}{\ifContinue}
  411. %    The switch \verb=\ifContinue= is used in various places in the
  412. %    program to indicate if a \verb=\loop= has to end.
  413. %    \begin{macrocode}
  414. \newif\ifContinue
  415. %    \end{macrocode}
  416. % \end{macro}
  417. % \begin{macro}{\ifTerminal}
  418. %    The macros that parse the boolean expression in the guards need
  419. %    a switch to indicate if a \meta{Terminal} has been found.
  420. % \changes{2.0l}{92/04/17}{Renamed from {\tt\bsl ifName}.}
  421. %    \begin{macrocode}
  422. \newif\ifTerminal
  423. %    \end{macrocode}
  424. % \end{macro}
  425. % \begin{macro}{\ifForlist}
  426. % \changes{2.0g}{91/06/05}{Macro added.}
  427. %    The program contains an implementation of a for-loop, based on
  428. %    plain \TeX{}'s \verb=\loop= macros. The implementation needs a
  429. %    switch to terminate the loop.
  430. %    \begin{macrocode}
  431. \newif\ifForlist
  432. %    \end{macrocode}
  433. % \end{macro}
  434. % \begin{macro}{\ifDefault}
  435. %    The switch \verb=\ifDefault= is used to indicate whether the
  436. %    default batch file has to be used.
  437. % \changes{2.0f}{91/06/04}{Macro added.} 
  438. %    \begin{macrocode}
  439. \newif\ifDefault
  440. %    \end{macrocode}
  441. % \end{macro}
  442. % \begin{macro}{\ifMoreFiles}
  443. %    The switch \verb=\ifMoreFiles= is used to decide if the user
  444. %    wants more files to be processed. It is used only in interactive
  445. %    mode; initially it evaluates to \meta{true}.
  446. % \changes{2.0h}{91/06/19}{Macro added.}
  447. %    \begin{macrocode}
  448. \newif\ifMoreFiles \MoreFilestrue
  449. %    \end{macrocode}
  450. % \end{macro}
  451. % \subsubsection{Count registers}
  452. % \begin{macro}{\blockLevel}
  453. %    Optionally included blocks of code can be nested. The counter
  454. %    \verb=\blockLevel= will be used to keep track of the level of
  455. %    nesting.  Its initial value is zero.
  456. %    \begin{macrocode}
  457. \newcount\blockLevel \blockLevel\z@
  458. %    \end{macrocode}
  459. % \end{macro}
  460. % \begin{macro}{\offLevel}
  461. %    The count register  \verb=\offLevel= is used to
  462. %    count the number of levels since the first block whose guard
  463. %    evaluated to false.  When this number reaches zero again we set the
  464. %    switch \verb=\ifOff= to fasle again.
  465. %    \begin{macrocode}
  466. \newcount\offLevel \offLevel \z@
  467. %    \end{macrocode}
  468. % \end{macro}
  469. % \begin{macro}{\emptyLines}
  470. %    The count register \verb=\emptyLines= is used to count the number
  471. %    of consecutive empty input lines. Only the first will be copied
  472. %    to the output file.
  473. % \changes{2.0i}{90/06/27}{Macro added}
  474. %    \begin{macrocode}
  475. \newcount\emptyLines \emptyLines \z@
  476. %    \end{macrocode}
  477. % \end{macro}
  478. % \begin{macro}{\processedLines}
  479. % \begin{macro}{\commentsRemoved}
  480. % \begin{macro}{\commentsPassed}
  481. % \begin{macro}{\codeLinesPassed}
  482. %    To be able to provide the user with some statistics about the
  483. %    stripping process four counters are allocated if the statistics
  484. %    have been included when this program was \ds{}ped.  The number of
  485. %    lines processed is stored in the counter \verb=\processedLines=.
  486. %    The number of lines containing comments that are not written on
  487. %    the output file is stored in the counter \verb=\commentsRemoved=;
  488. %    the number of comments copied to the output file is stored in the
  489. %    counter \verb=\commentsPassed=.  The number of lines containing
  490. %    macro code that are copied to the output file is stored in the
  491. %    counter \verb=\codeLinesPassed=.
  492. %    \begin{macrocode}
  493. %<*stats>
  494. \newcount\processedLines   \processedLines  \z@
  495. \newcount\commentsRemoved  \commentsRemoved \z@
  496. \newcount\commentsPassed   \commentsPassed  \z@
  497. \newcount\codeLinesPassed  \codeLinesPassed \z@
  498. %    \end{macrocode}
  499. % \end{macro}
  500. % \end{macro}
  501. % \end{macro}
  502. % \end{macro}
  503. % \begin{macro}{\NumberOfFiles}
  504. %    When more than one file is processed, the number of files is
  505. %    stored in the count register \verb=\NumberOfFiles= when
  506. %    statistics are included.
  507. %    \begin{macrocode}
  508. \newcount\NumberOfFiles \NumberOfFiles\z@
  509. %    \end{macrocode}
  510. % \end{macro}
  511. % \changes{2.0e}{91/05/31}{Added counter allocation for the processing
  512. %                           of multiple files}
  513. % \begin{macro}{\TotalprocessedLines}
  514. % \begin{macro}{\TotalcommentsRemoved}
  515. % \begin{macro}{\TotalcommentsPassed}
  516. % \begin{macro}{\TotalcodeLinesPassed}
  517. %    When more than one file is processed and when statistics have
  518. %    been included we provide the user also with information about the
  519. %    total amount of lines processed. For this purpose four more count
  520. %    registers are allocated here.
  521. %    \begin{macrocode}
  522. \newcount\TotalprocessedLines   \TotalprocessedLines  \z@
  523. \newcount\TotalcommentsRemoved  \TotalcommentsRemoved \z@
  524. \newcount\TotalcommentsPassed   \TotalcommentsPassed  \z@
  525. \newcount\TotalcodeLinesPassed  \TotalcodeLinesPassed \z@
  526. %</stats>
  527. %    \end{macrocode}
  528. % \end{macro}
  529. % \end{macro}
  530. % \end{macro}
  531. % \end{macro}
  532. % \subsubsection{I/O streams}
  533. % \begin{macro}{\inFile}
  534. % \begin{macro}{\outFile}
  535. %    For reading the file with documented \TeX-code, an input stream
  536. %    \verb=\inFile= is allocated. The stripped code is written on
  537. %    the output stream \verb=\outFile=.
  538. %    \begin{macrocode}
  539. \newread\inFile
  540. \newwrite\outFile
  541. %    \end{macrocode}
  542. % \end{macro}
  543. % \end{macro}
  544. % \changes{2.0e}{91/05/31}{Added allocation of extra input stream
  545. %                          for batch files}
  546. % \begin{macro}{\batchFile}
  547. %    For batch file processing an extra input stream is needed.
  548. %    \begin{macrocode}
  549. \newread\batchFile
  550. %    \end{macrocode}
  551. % \end{macro}
  552. % \begin{macro}{\ttyin}
  553. % \begin{macro}{\ttyout}
  554. %    For the communication with the user an input stream, \verb=\ttyin=
  555. %    and an output stream, \verb=\ttyout= are allocated.
  556. %    \begin{macrocode}
  557. \newread\ttyin
  558. \newwrite\ttyout
  559. %    \end{macrocode}
  560. % \end{macro}
  561. % \end{macro}
  562. % \begin{macro}{\batchinput}
  563. % \changes{2.0n}{92/04/26}{Added macro}
  564. % \begin{macro}{\skip@input}
  565. % \changes{2.0j}{92/03/03}{Added macro}
  566. % \changes{2.0n}{92/04/26}{Argument delimited by space not `relax}
  567. % \changes{2.0n}{92/04/26}{Macro renamed from `skipinput} When the
  568. %    file {\tt docstrip.tex} is read because of an \verb=\input=
  569. %    statement in a batch file we have to prevent an endless loop
  570. %    (well, limited by \TeX's stack). Therefore we save the original
  571. %    primitive \verb=\input= and define a new macro with an argument
  572. %    delimited by \verb*= = (i.e.\ a space) that just gobbles the
  573. %    argument.  Since the end-of-line character is converted by \TeX{}
  574. %    to a space.  This means that |\input| is not available as a
  575. %    command within batch files. We therefore keep a copy of the
  576. %    original under the name |\batchinput| which can be used if
  577. %    further batch commands are to be read from a different batch
  578. %    file.
  579. %    \begin{macrocode}
  580. \let\batchinput\input
  581. \def\skip@input#1 {}
  582. \let\input\skip@input
  583. %    \end{macrocode}
  584. % \end{macro}
  585. % \end{macro}
  586. % \subsubsection{Empty macros and macros that expand to a string}
  587. % \begin{macro}{\guardStack}
  588. %    \changes{2.0k}{92/04/06}{Renamed from {\tt\bsl blockStack}} Because
  589. %    blocks of code that will conditionally be included in the output
  590. %    can be nested, a stack is maintained to keep track of these
  591. %    blocks. The main reason for this is that we want to be able to
  592. %    check if the blocks are properly nested. The stack itself is
  593. %    stored in |\guardStack|.
  594. %    \begin{macrocode}
  595. \def\guardStack{}
  596. %    \end{macrocode}
  597. % \end{macro}
  598. % \begin{macro}{\blockHead}
  599. %    The macro \verb=\blockHead= is used for storing and retrieving
  600. %    the boolean expression that starts a block.
  601. %    \begin{macrocode}
  602. \def\blockHead{}
  603. %    \end{macrocode}
  604. % \end{macro}
  605. % \begin{macro}{\Options}
  606. % \begin{macro}{\lastOption}
  607. %    The list of options to include in the output is stored in
  608. %    \verb=\Options=. The macro \verb=\lastOption= is used to remember
  609. %    which option was started.
  610. %    \begin{macrocode}
  611. \def\Options{}
  612. \def\lastOption{}
  613. %    \end{macrocode}
  614. % \end{macro}
  615. % \end{macro}
  616. % \begin{macro}{\TrueExpression}
  617. % \begin{macro}{\FalseExpression}
  618. %    In the evaluation of the boolean expressions a representation is
  619. %    needed for \meta{true} and \meta{false}. This representation is
  620. %    realized by the definition of |\TrueExpression| and
  621. %    |\FalseExpression|. These macros are meant to be used with \TeX's
  622. %    |\if|-test.  When the expression |\if\TrueExpression...| is
  623. %    expanded by \TeX\ it yields |\if TT...|. This test is true and
  624. %    all instructions following the test (until |\else| or |\fi| is
  625. %    encountered) will examined.
  626. %    \begin{macrocode}
  627. \def\TrueExpression{TT}
  628. \def\FalseExpression{TF}
  629. %    \end{macrocode}
  630. % \end{macro}
  631. % \end{macro}
  632. % \begin{macro}{\yes}
  633. % \begin{macro}{\y}
  634. %    When the user is asked a question that he has to answer with either
  635. %    \meta{yes} or \meta{no}, his response has to be evaluated. For this
  636. %    reason the macros \verb=\yes= and \verb=\y= are defined.
  637. %    \begin{macrocode}
  638. \def\yes{yes}
  639. \def\y{y}
  640. %    \end{macrocode}
  641. % \end{macro}
  642. % \end{macro}
  643. % \begin{macro}{\Defaultbatchile}
  644. % \changes{2.0f}{91/06/04}{Macro added.}
  645. %    When the \ds{} program has to process a batch file it
  646. %    can look for a batch file with a default name. This name
  647. %    is stored in \verb=\DefaultbatchFile=.
  648. %    \begin{macrocode}
  649. \def\DefaultbatchFile{docstrip.cmd}
  650. %    \end{macrocode}
  651. % \end{macro}
  652. % \begin{macro}{\perCent}
  653. % \begin{macro}{\DoubleperCent}
  654. %    To be able to display percent-signs on the terminal, a {\tt\%}
  655. %    with category code 12 is stored in \verb=\perCent=. The macro
  656. %    \verb=\DoubleperCent= is used to write two percent-signs when
  657. %    writing the preamble of the output file.
  658. %    \begin{macrocode}
  659. {\catcode`\%=12
  660.  \gdef\perCent{%}
  661.  \gdef\DoubleperCent{%% }
  662. %    \end{macrocode}
  663. % \end{macro}
  664. % \end{macro}
  665. %    In order to allow formfeeds in the input we define a one-character
  666. %    control sequence \verb=^^L=.
  667. %    \begin{macrocode}
  668. \def^^L{ }
  669. %    \end{macrocode}
  670. % \subsubsection{Miscellaneous variables}
  671. % \begin{macro}{\inFileName}
  672. %    The macro \verb=\inFileName= is used to store the name of the
  673. %    current input file.
  674. % \end{macro}
  675. % \begin{macro}{\outFileName}
  676. %    The macro \verb=\outFileName= is used to store the name of the
  677. %    current output file.
  678. % \end{macro}
  679. % \begin{macro}{\batchfile}
  680. %    The macro \verb=\batchfile= is used to store the name of the
  681. %    batch file.
  682. % \end{macro}
  683. % \begin{macro}{\inLine}
  684. %    The macro \verb=\inLine= is used to store the lines, read from
  685. %    the input file, before further processing.
  686. % \end{macro}
  687. % \begin{macro}{\batchLine}
  688. %    The macro \verb=\batchLine= is used to store the lines, read from
  689. %    the batch file, before further processing.
  690. % \end{macro}
  691. % \begin{macro}{\nextToken}
  692. %    In this \TeX-program a lot of `peeking ahead' using the
  693. %    \verb=\futurelet= instruction is done. In such cases the
  694. %    character that appears first in the input stream is stored in
  695. %    \verb=\nextToken=.
  696. % \end{macro}
  697. % \begin{macro}{\doNext}
  698. %    Another aspect of this program is that quite often the next action
  699. %    depends on the evaluation of an \verb=\if= construct. In such cases
  700. %    the control sequence \verb=\doNext= is \verb=\let= to the macro
  701. %    that has to be executed.
  702. % \end{macro}
  703. % \begin{macro}{\answer}
  704. %    When some interaction with the user is needed the macro
  705. %    \verb=\answer= is used to store his response.
  706. % \end{macro}
  707. % \begin{macro}{\tmp}
  708. %    Sometimes something has to be temporarily stored in a control
  709. %    sequence.  For these purposes the control sequence \verb=\tmp= is
  710. %    used.
  711. % \end{macro}
  712. % \subsection{Support macros}
  713. %    \subsubsection{The stack mechanism}
  714. %    It is possible to have `nested guards'. This means that within a
  715. %    block of optionally included code a subgroup is only included
  716. %    when an additional option is specified. To keep track of the
  717. %    nesting of the guards the currently `open' guard can be pushed on
  718. %    the stack |\guardStack| and later popped off the stack again. The
  719. %    macros that implement this stack mechanism are loosely based on
  720. %    code that is developed in the context of the \LaTeX3 project.
  721. %    To be able to implement a stack mechanism we need a couple of
  722. %    support macros.
  723. % \begin{macro}{\eltStart}
  724. %    \changes{2.0k}{92/04/06}{Macro added}
  725. % \begin{macro}{\eltEnd}
  726. %    \changes{2.0k}{92/04/06}{Macro added}
  727. %    The macros |\eltStart| and |\eltEnd| are used to delimit a stack
  728. %    element. They are both empty.
  729. %    \begin{macrocode}
  730. \def\eltStart{}
  731. \def\eltEnd{}
  732. %    \end{macrocode}
  733. % \end{macro}
  734. % \end{macro}
  735. % \begin{macro}{\qStop}
  736. %    \changes{2.0k}{92/04/06}{Macro added}
  737. %    The macro |\qStop| is a so-called `quark', a macro that expands to
  738. %    itself\footnote{The concept of `quarks' is developed for the
  739. %    \LaTeX3 project.}.
  740. %    \begin{macrocode}
  741. \def\qStop{\qStop}
  742. %    \end{macrocode}
  743. % \end{macro}
  744. % \begin{macro}{\pop}
  745. %    \changes{2.0k}{92/04/06}{Macro added} The macro
  746. %    |\pop|\meta{stack}\meta{cs} `pops' the top element from the
  747. %    stack. It assigns the value of the top element to \meta{cs} and
  748. %    removes it from \meta{stack}. When \meta{stack} is empty a
  749. %    warning is issued and \meta{cs} is assigned an empty value.
  750. %    \begin{macrocode}
  751. \def\pop#1#2{%
  752.   \ifx#1\empty
  753.     \Msg{Warning: Found end guard without matching begin}%
  754.     \let#2\empty
  755.   \else
  756. %    \end{macrocode}
  757. %    To be able to `peel' off the first guard we use an extra macro
  758. %    |\popX| that receives both the expanded and the unexpanded stack
  759. %    in its arguments. The expanded stack is delimited with the quark
  760. %    |\qStop|.
  761. %    \begin{macrocode}
  762.     \def\tmp{\expandafter\popX #1\qStop #1#2}%
  763.     \expandafter\tmp\fi}
  764. %    \end{macrocode}
  765. % \begin{macro}{\popX}
  766. %    \changes{2.0k}{92/04/06}{Macro added} When the stack is expanded
  767. %    the elements are surrounded with |\eltStart| and |\eltEnd|. The
  768. %    first element of the stack is assigned to |#4|.
  769. %    \begin{macrocode}
  770. \def\popX\eltStart #1\eltEnd #2\qStop #3#4{\def#3{#2}\def#4{#1}}
  771. %    \end{macrocode}
  772. % \end{macro}
  773. % \end{macro}
  774. % \begin{macro}{\push}
  775. %    \changes{2.0k}{92/04/06}{Macro added}
  776. %    Guards can be pushed on the stack using the macro
  777. %    |\push|\meta{stack}\meta{guard}. Again we need a secondary macro
  778. %    (|\pushX|) that has both the expanded and the unexpanded stack as
  779. %    arguments.
  780. %    \begin{macrocode}
  781. \def\push#1#2{\expandafter\pushX #1\qStop #1{\eltStart #2\eltEnd}}
  782. %    \end{macrocode}
  783. % \begin{macro}{\pushX}
  784. %    \changes{2.0k}{92/04/06}{Macro added}
  785. %    The macro |\pushX| picks up the complete expansion of the stack as
  786. %    its first argument and places the guard in |#3| on the `top'.
  787. %    \begin{macrocode}
  788. \def\pushX #1\qStop #2#3{\def #2{#3#1}}
  789. %    \end{macrocode}
  790. % \end{macro}
  791. % \end{macro}
  792. % \subsubsection{Programming structures}
  793. % \begin{macro}{\forlist}
  794. % \changes{2.0g}{91/06/05}{Macro added.}
  795. %    When the program is used in interactive mode the
  796. %    user can supply a list of files that have to be processed.
  797. %    In order to process this list a for-loop is needed. This
  798. %    implementation of such a programming construct is based on the
  799. %    use of the \verb=\loop{=\meta{body}\verb=}\repeat= macro that
  800. %    is defined in plain \TeX\@. The syntax for this loop is:
  801. %    \begin{flushleft}
  802. %    \verb=\for=\meta{control sequence} \verb|:=| \meta{list} 
  803. %    \verb=\do=\\
  804. %    \meta{body}\\
  805. %    \verb=\od=
  806. %    \end{flushleft}
  807. %    The \meta{list} should be a comma separated list.
  808. %    The first actions that have to be taken are to set the switch
  809. %    \verb=\ifForlist= to \meta{true} and to store the loop condition
  810. %    in the macro \verb=\ListCondition=. This is done using an
  811. %    \verb=\edef= to allow for a control sequence that contains a
  812. %    \meta{list}.
  813. %    \begin{macrocode}
  814. \def\forlist#1:=#2\do#3\od{%
  815.     \edef\ListCondition{#2}%
  816.     \Forlisttrue
  817. %    \end{macrocode}
  818. %    Then we start the loop.
  819. %    We store the first element from the \verb=\ListCondition= in the
  820. %    macro that was supplied as the first argument to \verb=\forlist=.
  821. %    This element is then removed from the \verb=\ListCondition=.
  822. %    \begin{macrocode}
  823.     \loop
  824.       \edef#1{\expandafter\FirstElt\ListCondition,\empty.}%
  825.       \edef\ListCondition{\expandafter\OtherElts\ListCondition,\empty.}%
  826. %    \end{macrocode}
  827. %    When the first element from the \meta{list} is empty, we are done
  828. %    processing, so we switch \verb=\ifForlist= to \meta{false}.
  829. %    When it is not empty we execute the third argument that should
  830. %    contain \TeX\ commands to execute.
  831. %    \begin{macrocode}
  832.       \ifx#1\empty \Forlistfalse \else#3\fi
  833. %    \end{macrocode}
  834. %    Finally we test the switch \verb=\ifForlist= to decide whether the
  835. %    loop has to be continued.
  836. %    \begin{macrocode}
  837.       \ifForlist
  838.     \repeat}
  839. %    \end{macrocode}
  840. % \begin{macro}{\FirstElt}
  841. % \changes{2.0g}{91/06/05}{Macro added.}
  842. %    The macro \verb=\FirstElt= is used to get the first element from a
  843. %    comma-separated list.
  844. %    \begin{macrocode}
  845. \def\FirstElt#1,#2.{#1}
  846. %    \end{macrocode}
  847. % \end{macro}
  848. % \begin{macro}{\OtherElts}
  849. % \changes{2.0g}{91/06/05}{Macro added.}
  850. %    The macro \verb=\OtherElts= is used to get all elements {\em but\/}
  851. %    the first element from a comma-separated list.
  852. %    \begin{macrocode}
  853. \def\OtherElts#1,#2.{#2}
  854. %    \end{macrocode}
  855. % \end{macro}
  856. % \end{macro}
  857. % \begin{macro}{\whileswitch}
  858. % \changes{2.0h}{91/06/19}{Macro added.} When the program is used in
  859. %    interactive mode the user might want to process several files
  860. %    with different options or extensions.  This goal could be reached
  861. %    by running the program several times, but it is more
  862. %    user-friendly to ask if he would like to process more files when
  863. %    we are done processing his last request.  To accomplish this we
  864. %    need the implementation of a {\tt while}-loop.  Again plain
  865. %    \TeX's \verb=\loop{=\meta{body}\verb=}\repeat= is used to
  866. %    implement this programming structure.
  867. %    The syntax for this loop is:
  868. %    \begin{flushleft}
  869. %    \verb=\whileswitch=\meta{switch} \verb|\fi| \meta{list}
  870. %    \verb={=\meta{body}\verb=}=\\
  871. %    \end{flushleft}
  872. %    The first argument to this macro has to be a switch, defined
  873. %    using \verb=\newif=; the second argument contains the statements
  874. %    to execute while the switch evaluates to \meta{true}.
  875. %    \begin{macrocode}
  876. \def\whileswitch#1\fi#2{#1\loop#2#1\repeat\fi}
  877. %    \end{macrocode}
  878. % \end{macro}
  879. % \subsubsection{Input and Output}
  880. % \begin{macro}{\maybeMsg}
  881. % \begin{macro}{\showprogress}
  882. % \begin{macro}{\keepsilent}
  883. %    When this program is used it can optionally show its progress on
  884. %    the terminal. In that case it will write a special character to
  885. %    the terminal (and the transcript file) for each input line. This
  886. %    option is on by default when statistics are included in {\tt
  887. %    docstrip.tex}. It is off when statistics are excluded. The
  888. %    commands \verb=\showprogress= and \verb=\keepsilent= can be used
  889. %    to choose otherwise.
  890. %    \begin{macrocode}
  891. \def\showprogress{\let\maybeMsg\message}
  892. \def\keepsilent{\let\maybeMsg\gobble}
  893. %<*stats>
  894. \showprogress
  895. %</stats>
  896. %<-stats>\keepsilent
  897. %    \end{macrocode}
  898. % \end{macro}
  899. % \end{macro}
  900. % \end{macro}
  901. % \begin{macro}{\Msg}
  902. %    For displaying messages on the terminal the macro \verb=\Msg= is
  903. %    defined to write {\em immediately\/} to \verb=\ttyout=.
  904. %    \begin{macrocode}
  905. \def\Msg{\immediate\write\ttyout}
  906. %    \end{macrocode}
  907. % \end{macro}
  908. % \begin{macro}{\Ask}
  909. %    The macro \verb=\Ask{=\meta{cs}{\tt\}\{}\meta{string}{\tt\}}
  910. %    is a slightly modified copy of the \LaTeX\ macro
  911. %    \verb=\typein=. It is used to ask the user a question.
  912. %    The \meta{string} will be displayed on his terminal and
  913. %    the response will be stored in the \meta{cs}. The trailing space
  914. %    left over from the carriage return is stripped off by the macro
  915. %    \verb=\strip=. If the user just types a carriage return, the result
  916. %    will be an empty macro.
  917. % \changes{2.0i}{91/06/27}{Added check for just \protect\meta{CR}}
  918. %    \begin{macrocode}
  919. \def\iden#1{#1}
  920. \def\strip#1#2 \gobble{\def #1{#2}}
  921. \def\@defpar{\par}
  922. \def\Ask#1#2{%
  923.     \message{#2}\read\ttyin to #1\ifx#1\@defpar\def#1{}\else
  924.     \iden{\expandafter\strip\expandafter#1#1\gobble\gobble} \gobble\fi}
  925. %    \end{macrocode}
  926. % \end{macro}
  927. % \begin{macro}{\WriteOut}
  928. % \changes{2.0e}{91/06/01}{Macro added.} When a line has to be written
  929. %    on the output file this can be done using the macro
  930. %    \verb=\WriteOut=. It writes a `{\tt.}' on the terminal and
  931. %    \verb=\immediate=ly writes it argument to \verb=\outFile=.
  932. %    \begin{macrocode}
  933. \def\WriteOut#1{\maybeMsg{.}\immediate\write\outFile{#1}}
  934. %    \end{macrocode}
  935. % \end{macro}
  936. % \subsubsection{Miscellaneous}
  937. % \begin{macro}{\OffStart}
  938. %    When the start of a block of code that has to be excluded from
  939. %    the output is encountered the macro \verb=\Offstart= is called.
  940. %    This macro sets the switch \verb=\ifOff= to \meta{true} and
  941. %    increments the counter \verb=\offLevel= by $1$.
  942. %    \begin{macrocode}
  943. \def\OffStart{\Offtrue\advance\offLevel\@ne}
  944. %    \end{macrocode}
  945. % \end{macro}
  946. % \begin{macro}{\OffEnd}
  947. %    At the end of a block of code that is excluded the macro
  948. %    \verb=\OffEnd= is called. It decrements the counter by $1$ and if
  949. %    the value of the counter is $0$, it switches \verb=\ifOff= to
  950. %    \meta{false}.
  951. %    \begin{macrocode}
  952. \def\OffEnd{%
  953.     \advance\offLevel\m@ne
  954.     \ifnum\offLevel=\z@
  955.       \Offfalse
  956.     \fi}
  957. %    \end{macrocode}
  958. % \end{macro}
  959. % \begin{macro}{\gobble}
  960. % \changes{2.0a}{91/05/25}{Macro added.}
  961. %    A macro that has an argument and puts it in the bitbucket.
  962. %    \begin{macrocode}
  963. \def\gobble#1{}
  964. %    \end{macrocode}
  965. % \end{macro}
  966. % \begin{macro}{\Endinput}
  967. % \changes{2.0f}{91/06/04}{Macro added.} When a {\tt doc} file
  968. %    contains a \verb+\endinput+ on a line by itself this normally
  969. %    means that anything following in this file should be ignored.
  970. %    Therefore we need a macro containing \verb=\endinput= as its
  971. %    replacement text to check this against \verb=\inLine= (the
  972. %    current line from the current input file). Of course the
  973. %    backslash has to have the correct \verb=\catcode=. One way of
  974. %    doing this is feeding \verb=\\= to the \verb=\string= operation
  975. %    and afterwards removing one of the \verb=\= characters.
  976. %    \begin{macrocode}
  977. \edef\Endinput{\expandafter\gobble\string\\endinput}
  978. %    \end{macrocode}
  979. % \end{macro}
  980. % \begin{macro}{\makeOther}
  981. %    During the process of reading a file with \TeX\ code the category
  982. %    code of all special characters has to be changed to \meta{other}.
  983. %    The macro \verb=\makeOther= serves this purpose.
  984. %    \begin{macrocode}
  985. \def\makeOther#1{\catcode`#1=12\relax}
  986. %    \end{macrocode}
  987. % \end{macro}
  988. % \begin{macro}{\end}
  989. % \changes{2.0h}{91/06/19}{Macro added.} For now we want the \ds{}
  990. %    program to be compatible with both plain \TeX\ and \LaTeX\@.
  991. %    \LaTeX\ version 2.09 hides plain \TeX{}'s \verb=\end= command and
  992. %    calls it \verb=\@@end=. We unhide it here.
  993. %    \begin{macrocode}
  994. \ifx\undefined\@@end\else\let\end\@@end\fi
  995. %    \end{macrocode}
  996. % \end{macro}
  997. % \subsection{The evaluation of boolean expressions}
  998. %    For clarity we repeat here the syntax for the boolean expressions
  999. %    as it was given before:
  1000. %\DeleteShortVerb\|
  1001. %    \begin{tabular}{lcl}
  1002. %    \meta{Expression} & $::=$ & \meta{Primary}
  1003. %                                [\{{\tt|}, {\tt,}\} \meta{Primary}]*\\
  1004. %    \meta{Primary}    & $::=$ & 
  1005. %                         \meta{Secondary} [{\tt\&} \meta{Secondary}]*\\
  1006. %    \meta{Secondary}  & $::=$ & 
  1007. %                         \meta{Terminal} $|$ {\tt!}\meta{Secondary}
  1008. %                                  $|$ {\tt(}\meta{Expression}{\tt)}\\
  1009. %    \end{tabular}
  1010. %    The {\tt|} stands for disjunction, the {\tt\&} stands for
  1011. %    conjunction and the {\tt!}\ stands for negation. The
  1012. %    \meta{Terminal} is any sequence of letters and evaluates to
  1013. %    \meta{true} iff it occurs in the list of options that have to be
  1014. %    included.
  1015. %\MakeShortVerb\|
  1016. % \subsubsection{Parsing intermediate results} The parsing of the
  1017. %    boolean expressions has to be carried out very carefully. The
  1018. %    parsing of an expression starts at the `left side'.  Each term in
  1019. %    the expression is fully parsed before the next term is examined.
  1020. %    This parsing occurs inside a group, so macros can be redefined
  1021. %    without affecting the result of the total evaluation.  As a
  1022. %    consequence of this, the result of the evaluation has to be
  1023. %    passed to the outer level. For this purpose the control sequence
  1024. %    |\expressionValue| is used.
  1025. %    This is done as follows:\\ A macro |\doNext| is defined using the
  1026. %    |\edef| command.  It closes the group that was started when the
  1027. %    evaluation of this term started; then it calls the macro
  1028. %    |\PropagateValue| with the result of the evaluation as its
  1029. %    argument.  Note that because of the use of |\edef| the control
  1030. %    sequence |\expressionValue| will be replaced by either {\tt TT}
  1031. %    or {\tt TF} in the replacement text for |\doNext|. The macro is
  1032. %    then executed.
  1033. %\begin{verbatim}
  1034. %  \edef\doNext{\endgroup\noexpand\PropagateValue{\ExpressionValue}}%
  1035. %  \doNext
  1036. %\end{verbatim}
  1037. % \begin{macro}{\PropagateValue}
  1038. %    The `top level' definition of the macro |\PropagateValue| just
  1039. %    stores its (expanded) argument in |\expressionValue|. Note that
  1040. %    this macro is redefined during various phases of the parsing
  1041. %    process.
  1042. %    \begin{macrocode}
  1043. \def\PropagateValue#1\qStop{%
  1044.   \edef\ExpressionValue{#1}}
  1045. %    \end{macrocode}
  1046. % \begin{macro}{\ContinueExpression}
  1047. %    During the parsing of an \meta{Expression} the control sequence
  1048. %    |\PropagateValue| is |\let| to |\ContinueExpression|. The argument
  1049. %    of this macro is either {\tt TT} or {\tt TF}, being the result of
  1050. %    the parsing of the current term.
  1051. %    \begin{macrocode}
  1052. \def\ContinueExpression#1{%
  1053. %    \end{macrocode}
  1054. %    A logical-or of this result and the accumulated result of all
  1055. %    previous terms is performed. This means that if the result so far
  1056. %    was \meta{true} it remains \meta{true}, otherwise the current
  1057. %    term determines the total result so far.
  1058. %    \begin{macrocode}
  1059.   \if\ExpressionValue
  1060.   \else
  1061.     \def\ExpressionValue{#1}%
  1062.   \fi
  1063. %    \end{macrocode}
  1064. %    Then we peek at the next token using |\futurelet| and call
  1065. %    |\ContinueExpressionX| to decide what to do, depending on the
  1066. %    next token.
  1067. %    \begin{macrocode}
  1068.   \futurelet\nextToken\ContinueExpressionX}
  1069. %    \end{macrocode}
  1070. % \end{macro}
  1071. % \begin{macro}{\ContinueExpressionX}
  1072. %    When the macro |\ContinueExpressionX| is called, the next token
  1073. %    is stored in the control sequence |\nextToken|.
  1074. %    \begin{macrocode}
  1075. \def\ContinueExpressionX{%
  1076. %    \end{macrocode}
  1077. %\DeleteShortVerb\|
  1078. %    If it is either {\tt|} or {\tt,} the parsing has to continue and
  1079. %    the next \meta{Pimary} term is considered.
  1080. %    \begin{macrocode}
  1081.   \ifx|\nextToken
  1082.     \def\doNext|{\Primary}%
  1083.   \else
  1084.     \ifx,\nextToken
  1085.       \def\doNext,{\Primary}%
  1086.     \else
  1087. %    \end{macrocode}
  1088. %    The only other character that can be encountered is the {\tt)}
  1089. %    that closes the expression. In that case we propagate the value
  1090. %    accumulated so far to the outer level.
  1091. %    \begin{macrocode}
  1092.       \edef\doNext){\endgroup\noexpand\PropagateValue{\ExpressionValue}}
  1093.     \fi
  1094.   \fi
  1095.   \doNext}
  1096. %    \end{macrocode}
  1097. %    Note that the characters {\tt|}, {\tt,} and {\tt)} have remained
  1098. %    in \TeX's input and have to be removed.
  1099. %    This is accomplished by including the character
  1100. %    in the parameter text of the definition of the macro
  1101. %    \verb=\doNext=.
  1102. % \end{macro}
  1103. %\MakeShortVerb\|
  1104. % \begin{macro}{\ContinuePrimary}
  1105. %    During the parsing of a \meta{Primary} term the control sequence
  1106. %    |\PropagateValue| is |\let| to |\ContinuePrimary|. The argument
  1107. %    of this macro is either {\tt TT} or {\tt TF}, being the result of
  1108. %    the parsing of the current term.
  1109. %    \begin{macrocode}
  1110. \def\ContinuePrimary#1{%
  1111. %    \end{macrocode}
  1112. %    A logical-and of this result and the accumulated result of all
  1113. %    previous terms is performed. This means that if the result so far
  1114. %    was \meta{false} it remains \meta{false}, otherwise the current
  1115. %    term determines the total result so far.
  1116. %    \begin{macrocode}
  1117.   \if\ExpressionValue
  1118.     \def\ExpressionValue{#1}%
  1119.   \fi
  1120. %    \end{macrocode}
  1121. %    Then we peek at the next token using |\futurelet| and call
  1122. %    |\ContinuePrimaryX| to decide what to do, depending on the
  1123. %    next token.
  1124. %    \begin{macrocode}
  1125.   \futurelet\nextToken\ContinuePrimaryX}
  1126. %    \end{macrocode}
  1127. % \end{macro}
  1128. % \begin{macro}{\ContinuePrimaryX}
  1129. %    When the macro |\ContinuePrimaryX| is called, the next token
  1130. %    is stored in the control sequence |\nextToken|. Because this macro
  1131. %    needs to check if the next token is a `{\tt\&}' we have to change
  1132. %    its category code before |\ContinuePrimaryX| is defined.
  1133. %    \begin{macrocode}
  1134. {\catcode`\&=12
  1135. \gdef\ContinuePrimaryX{%
  1136. %    \end{macrocode}
  1137. %    If the next token is {\tt\&} the parsing has to continue and
  1138. %    the next \meta{Secondary} term is considered.
  1139. %    \begin{macrocode}
  1140.   \ifx&\nextToken
  1141.     \def\doNext&{\Secondary}%
  1142.   \else
  1143. %    \end{macrocode}
  1144. %    Any other character indicates the end of the current term.
  1145. %    In that case we propagate the value accumulated
  1146. %    so far to the outer level.
  1147. %    \begin{macrocode}
  1148.     \edef\doNext{\endgroup\noexpand\PropagateValue{\ExpressionValue}}%
  1149.   \fi
  1150.   \doNext}}
  1151. %    \end{macrocode}
  1152. % \end{macro}
  1153. % \end{macro}
  1154. % \begin{macro}{\PropagateNegatedValue}
  1155. %    When a \meta{Secondary} term is preceded by a {\tt!}\ character the
  1156. %    the control sequence |\PropagateValue| is |\let| to
  1157. %    |\PropagateNegatedValue|. The only function of this macro is
  1158. %    to propagate the negation of its argument.
  1159. %    \begin{macrocode}
  1160. \def\PropagateNegatedValue#1{%
  1161.   \edef\doNext{\endgroup
  1162.     \noexpand\PropagateValue
  1163.     {\if#1%
  1164.        \noexpand\FalseExpression
  1165.      \else
  1166.        \noexpand\TrueExpression
  1167.      \fi}}%
  1168.   \doNext}
  1169. %    \end{macrocode}
  1170. % \end{macro}
  1171. % \subsubsection{The evaluation of the boolean expression}
  1172. % \begin{macro}{\Evaluate}
  1173. %    To start the parsing of a boolean expression the macro |\Evaluate|
  1174. %    is called by the macros |\testOption| and |\starOption|
  1175. %    |\Evaluate| encloses its argument with {\tt ()} and appends
  1176. %    |\qStop|.  The result is passed on to \verb=\Expression= for
  1177. %    further processing.  The parentheses are added to ease the
  1178. %    parsing by |\Expression|.
  1179. %    \begin{macrocode}
  1180. \def\Evaluate#1{%
  1181.   \Expression(#1)\qStop}
  1182. %    \end{macrocode}
  1183. % \end{macro}
  1184. % \begin{macro}{\Expression}
  1185. %    The definition of the macro |\Expression| includes a `{\tt(}' in
  1186. %    the parameter text of the macro; this causes the immediate
  1187. %    removal of the first parenthesis that encloses the expression.
  1188. %    \begin{macrocode}
  1189. \def\Expression({%
  1190. %    \end{macrocode}
  1191. %    It then starts a group,
  1192. %    \begin{macrocode}
  1193.   \begingroup
  1194. %    \end{macrocode}
  1195. %    initialises the
  1196. %    |\ExpressionValue| to \meta{false}
  1197. %    \begin{macrocode}
  1198.     \let\ExpressionValue\FalseExpression
  1199. %    \end{macrocode}
  1200. %    and calls |\Primary| to
  1201. %    continue the parsing process.
  1202. %    \begin{macrocode}
  1203.     \let\PropagateValue\ContinueExpression
  1204.     \Primary}
  1205. %    \end{macrocode}
  1206. %    |\ExpressionValue| is set to \meta{false} because the logical-or
  1207. %    of this value and the result of the first term will be performed.
  1208. % \end{macro}
  1209. % \begin{macro}{\Primary}
  1210. %    The macro |\Primary| is used to parse \meta{Primary} terms. Like
  1211. %    |\expression| it starts a group. It then initiates the
  1212. %    |ExpressionValue| appropriately and calls |\Secondary| to
  1213. %    continue the parsing process.
  1214. %    \begin{macrocode}
  1215. \def\Primary{%
  1216.   \begingroup
  1217.     \let\ExpressionValue\TrueExpression
  1218.     \let\PropagateValue\ContinuePrimary
  1219.     \Secondary}
  1220. %    \end{macrocode}
  1221. % \end{macro}
  1222. % \begin{macro}{\Secondary}
  1223. %    As can be seen in the syntax of boolean expressions a
  1224. %    \meta{Secondary} term can contain three different kinds of term.
  1225. %    When the first token of the \meta{Secondary} is a `{\tt!}' the
  1226. %    result of the parsing of the term should be negated; when the
  1227. %    first token is a `{\tt(}'it indicates the start of a
  1228. %    subexpression. Any other token is part of a \meta{Terminal}.
  1229. %    Therefore we have to inspect the first token of the term and decide
  1230. %    what to do. This is acheived by using |\futurelet| and calling
  1231. %    |\SecondaryX|.
  1232. %    \begin{macrocode}
  1233. \def\Secondary{%
  1234.   \futurelet\nextToken\SecondaryX}
  1235. %    \end{macrocode}
  1236. % \begin{macro}{\SecondaryX}
  1237. %    When this macro is called, the control sequence |\nextToken|
  1238. %    contains a copy of the first character of the term being inspected.
  1239. %    \begin{macrocode}
  1240. \def\SecondaryX{%
  1241. %    \end{macrocode}
  1242. %    When |\nextToken| contains a `{\tt(}' we make sure that calling
  1243. %    |\doNext| is actually a call of |\Expression| to
  1244. %    parse the subexpression.
  1245. %    \begin{macrocode}
  1246.   \ifx\nextToken(\let\doNext\Expression\else
  1247. %    \end{macrocode}
  1248. %    When |\nextToken| contains a `{\tt!}' we make sure that calling
  1249. %    |\doNext| is actually a call of |\Negate| to negate the result
  1250. %    of the following term.
  1251. %    \begin{macrocode}
  1252.   \ifx\nextToken!\let\doNext\Negate\else
  1253. %    \end{macrocode}
  1254. %    If |\nextToken| contains anything else |\doNext| is |\let|
  1255. %    to |\Terminal|.
  1256. %    \begin{macrocode}
  1257.                  \let\doNext\Terminal\fi\fi
  1258. %    \end{macrocode}
  1259. %    The call of |\doNext| will now start the proper macro.
  1260. %    \begin{macrocode}
  1261.   \doNext}
  1262. %    \end{macrocode}
  1263. % \end{macro}
  1264. % \end{macro}
  1265. % \begin{macro}{\Negate}
  1266. %    When during the parsing of a \meta{Secondary} term a `|!|' is
  1267. %    encountered the result has to be negated. Therefore a new group
  1268. %    is started, |\PropagateValue| is made equivalent to
  1269. %    |\PropagateNegatedValue| and |\Secondary| is called again.
  1270. %    \begin{macrocode}
  1271. \def\Negate!{%
  1272.   \begingroup
  1273.     \let\PropagateValue\PropagateNegatedValue
  1274.     \Secondary}
  1275. %    \end{macrocode}
  1276. % \end{macro}
  1277. % \begin{macro}{\Terminal}
  1278. %    The parsing of a \meta{Terminal} is done token by token. Therefore
  1279. %    we accumulate the tokens that make up the \meta{Terminal} in
  1280. %    the token register |\TerminalString|. This register is cleared and
  1281. %    processing starts with calling |\TerminalX|.
  1282. %    \begin{macrocode}
  1283. \def\Terminal{%
  1284.   \global\TerminalString{}\TerminalX}
  1285. %    \end{macrocode}
  1286. % \begin{macro}{\TerminalX}
  1287. %    The macro |\TerminalX| scoops up the next token and appends it to
  1288. %    |\TerminalString|. It can do that because the token has been
  1289. %    examined before by another macro, either |\Secondary| (at the start
  1290. %    of this process) or |\TerminalXX| (during this process).
  1291. %    \begin{macrocode}
  1292. \def\TerminalX#1{%
  1293.   \global\TerminalString\expandafter{\the\TerminalString#1}%
  1294. %    \end{macrocode}
  1295. %    Now we have to peek at the next token again to decide what the
  1296. %    next action should be. The decision will be taken by |\TerminalXX|.
  1297. %    \begin{macrocode}
  1298.   \futurelet\nextToken\TerminalXX}
  1299. %    \end{macrocode}
  1300. % \begin{macro}{\TerminalXX}
  1301. %\DeleteShortVerb\|\MakeShortVerb\+
  1302. %    The macro +\TerminalXX+ uses the contents of +\nextToken+ to
  1303. %    decide what the next action should be. When +\nextToken+
  1304. %    contains one of `{\tt\&}', `{\tt|}', `{\tt,}', `{\tt!}',
  1305. %    `{\tt(}' or `{\tt)}' the end of the \meta{Terminal} has been
  1306. %    found and processing should stop; when +\nextToken+ contains
  1307. %    any other character it is part of the \meta{Terminal}.
  1308. %    During the definition of the macro the `{\tt\&}' should be
  1309. %    {\tt\&$_{12}$} so its category code needs to be changed.
  1310. %    \begin{macrocode}
  1311. {\catcode`\&=12
  1312. \gdef\TerminalXX{%
  1313. %    \end{macrocode}
  1314. %    A couple of +\ifx+ tests are needed to decide whether the
  1315. %    \meta{Terminal} that is being accumulated has ended. We use
  1316. %    the switch +\ifTerminal+ to inidicate whether this has happend
  1317. %    or not. It is initialised to \meta{false} (meaning: ``the end has
  1318. %    been found'').
  1319. %    \begin{macrocode}
  1320.   \Terminalfalse
  1321.   \ifx &\nextToken \else
  1322.   \ifx |\nextToken \else
  1323.   \ifx ,\nextToken \else
  1324.   \ifx !\nextToken \else
  1325.   \ifx (\nextToken \else
  1326.   \ifx )\nextToken \else
  1327. %    \end{macrocode}
  1328. %    If none of the above tests are \meta{true} the end of the
  1329. %    \meta{Terminal} has {\em not\/} been found, so the switch is
  1330. %    set to \meta{true}.
  1331. %    \begin{macrocode}
  1332.     \Terminaltrue
  1333.   \fi\fi\fi\fi\fi\fi
  1334. %    \end{macrocode}
  1335. %    If the \meta{Terminal} has not ended the next character can be
  1336. %    appended to +\TerminalString+. This is accomplished by the
  1337. %    (recursive) call of +\TerminalX+.
  1338. %    \begin{macrocode}
  1339.   \ifTerminal
  1340.     \let\doNext\TerminalX
  1341. %    \end{macrocode}
  1342. %    When, on the other hand, the end {\em was\/} found, we have to
  1343. %    check whether the option (that is now stored in
  1344. %    +\TerminalString+) was amongst the options that needed to be
  1345. %    included in the output.  This check is performed by the macro
  1346. %    +\SetValue+. It gives +\ExpressionValue+ the appropriate value.
  1347. %    The token register is cleared when its contents are no longer
  1348. %    needed.
  1349. %    \begin{macrocode}
  1350.   \else
  1351.     \edef\doNext{\noexpand\SetValue{\the\TerminalString}}%
  1352.     \global\TerminalString{}%
  1353.   \fi
  1354. %    \end{macrocode}
  1355. %    At this point the macro +\doNext+ `points' to the macro that should
  1356. %    be executed, so we call it. The second brace closes the group that
  1357. %    was started to keep the category change of the character `{\tt\&}'
  1358. %    local.
  1359. %    \begin{macrocode}
  1360.   \doNext}
  1361. %    \end{macrocode}
  1362. %\MakeShortVerb\|\DeleteShortVerb\+
  1363. % \end{macro}
  1364. % \end{macro}
  1365. % \end{macro}
  1366. % \begin{macro}{\SetValue}
  1367. %    The macro |\Setvalue| has to check whether its argument is included
  1368. %    in the option list, stored in |\Options| as a comma-separated list.
  1369. %    \begin{macrocode}
  1370. \def\SetValue#1{%
  1371. %    \end{macrocode}
  1372. %    The actual check will be performed by a temporary macro |\tmp|.
  1373. %    The argument of |\SetValue| is made part of its argument text.
  1374. %    The argument text is delimited by |\qStop|. When |\tmp| is
  1375. %    executed it will have both the expanded optionlist and the
  1376. %    argument of |\SetValue| amongst its parameters. When the argument
  1377. %    of |\Setvalue| does {\em not\/} appear in |\Options| the second
  1378. %    argument of |\tmp| will be empty.
  1379. %    \begin{macrocode}
  1380.   \def\tmp##1,#1,##2\qStop{%
  1381. %    \end{macrocode}
  1382. %    To be able to check if the second argument is empty, we store it
  1383. %    in a temporary control secquence |\tmp|.
  1384. %    \begin{macrocode}
  1385.     \def\tmp{##2}%
  1386. %    \end{macrocode}
  1387. %    Then we define |\doNext|, using |\edef|, to propagate the value
  1388. %    of this expression to the outer level. Because we use |\edef|,
  1389. %    the replacement text of |\doNext| will contain either
  1390. %\begin{verbatim}
  1391. %    \PropagateValue{TF}
  1392. %\end{verbatim}
  1393. %    or
  1394. %\begin{verbatim}
  1395. %    \PropagateValue{FF}
  1396. %\end{verbatim}
  1397. %    \begin{macrocode}
  1398.     \edef\doNext{\noexpand\PropagateValue
  1399.       {\ifx\tmp\empty\FalseExpression\else\TrueExpression\fi}}%
  1400. %    \end{macrocode}
  1401. %    The last action of |\tmp| is to call the macro |\doNext| that it
  1402. %    has just defined.
  1403. %    \begin{macrocode}
  1404.     \doNext}%
  1405. %    \end{macrocode}
  1406. %    As stated before, we need the expansion of |\Options| in the
  1407. %    arguments of |\tmp|, therefore we have to delay the expansion of
  1408. %    |\tmp| using |\expandafter| until |\Options| has been expanded.
  1409. %    \begin{macrocode}
  1410.   \expandafter\tmp\expandafter,\Options,#1,\qStop}
  1411. %    \end{macrocode}
  1412. % \end{macro}
  1413. %  \subsection{Processing the input lines}
  1414. % \begin{macro}{\copyLine}
  1415. %    The macro \verb=\copyLine= writes its argument (which has to be
  1416. %    delimited with \verb=\endLine=) on the output file using the
  1417. %    macro \verb=\WriteOut=.  If statistics are included, the counter
  1418. %    \verb=\codeLinesPassed= is incremented by $1$.
  1419. %    \begin{macrocode}
  1420. \def\copyLine#1\endLine{%
  1421. %<*stats>
  1422.   \advance\codeLinesPassed\@ne
  1423. %</stats>
  1424.   \WriteOut{#1}}
  1425. %    \end{macrocode}
  1426. % \end{macro}
  1427. % \begin{macro}{\removeLine}
  1428. %    The macro |\removeLine| throws its argument (which has to be
  1429. %    delimited with |\endLine|) away. It writes a `{\tt\%}' on the
  1430. %    terminal if messages are enabled.
  1431. %    \begin{macrocode}
  1432. \def\removeLine#1\endLine{%
  1433.     \maybeMsg{\perCent}}
  1434. %    \end{macrocode}
  1435. % \end{macro}
  1436. % \begin{macro}{\removeComment}
  1437. %    The macro \verb=\removeComment= has nearly the same function as the
  1438. %    macro \verb=\removeLine=, except that when statistics are included
  1439. %    in the program the removed comment is counted. If statistics are
  1440. %    {\em not\/} included the macro \verb=\removeComment= is \verb=\let=
  1441. %    to \verb=\removeLine=.
  1442. %    \begin{macrocode}
  1443. %<*stats>
  1444. \def\removeComment#1\endLine{%
  1445.     \advance\commentsRemoved\@ne
  1446.     \maybeMsg{\perCent}}
  1447. %</stats>
  1448. %<-stats>\let\removeComment\removeLine
  1449. %    \end{macrocode}
  1450. % \end{macro}
  1451. % \begin{macro}{\putMetaComment}
  1452. %    If a line starts with two consecutive percent signs, it is
  1453. %    considered to be a {\em MetaComment\/}. Such a comment line is
  1454. %    passed on to the output file unmodified.
  1455. %    \begin{macrocode}
  1456. \def\putMetaComment#1\endLine{%
  1457. %    \end{macrocode}
  1458. %    To `close' a pending option the macro \verb=\closeOption= is
  1459. %    called.
  1460. %    \begin{macrocode}
  1461.   \closeOption%
  1462. %    \end{macrocode}
  1463. %    If statistics are included the line is counted.
  1464. %    \begin{macrocode}
  1465. %<*stats>
  1466.   \advance\commentsPassed\@ne
  1467. %</stats>
  1468. %    \end{macrocode}
  1469. %    The macro \verb=\putMetaComment= has one argument, delimited with
  1470. %    \verb=\endLine=. But because of earlier processing the argument
  1471. %    is discarded and \verb=\inLine=, which contains the complete line
  1472. %    as it was read from \verb=\inFile=, is written on
  1473. %    \verb=\outFile=.
  1474. %    \begin{macrocode}
  1475.   \WriteOut{\inLine}}
  1476. %    \end{macrocode}
  1477. % \end{macro}
  1478. % \begin{macro}{\processLine}
  1479. %    Each line that is read from the input stream has to be processed
  1480. %    to see if it has to be written on the output stream. This task
  1481. %    is performed by calling the macro \verb=\processLine=.
  1482. %    The macro increments the counter \verb=\processedLines= by $1$ if
  1483. %    statistics are included. Then it peeks at the next character
  1484. %    in the input stream by using \verb=\futurelet= and calling
  1485. %    \verb=\processLineX= to do the work.
  1486. %    \begin{macrocode}
  1487. \def\processLine{%
  1488. %<*stats>
  1489.   \advance\processedLines\@ne
  1490. %</stats>
  1491.   \futurelet\nextToken\processLineX}
  1492. %    \end{macrocode}
  1493. % \end{macro}
  1494. % \begin{macro}{\processLineX}
  1495. %    The macro \verb=\processLineX= has to check whether the current
  1496. %    line has to be included in the output or not. In order to do
  1497. %    that, it needs to check whether the line starts with a `{\tt\%}'.
  1498. %    Therefore the macro is globally defined within a group. Within
  1499. %    this group the category code of `{\tt\%}' is changed to 12
  1500. %    (other).  Because a comment character is needed, the category
  1501. %    code of `{\tt\#}' is changed to 14 (comment character).
  1502. %    When this macro is executed \TeX\ has stored the next token in
  1503. %    the input stream in \verb=\nextToken=. If it is a `{\tt\%}'
  1504. %    further processing has to be done by \verb=\processLineXX=;
  1505. %    otherwise we close the current option.\\ The setting of the
  1506. %    switch \verb=\ifOff= determines whether the current line is
  1507. %    either removed or copied.  Whatever action has to be taken, it
  1508. %    will be stored in the macro \verb=\doNext=, after the processing
  1509. %    of the \verb=\if=-statements is finished.
  1510. %    \begin{macrocode}
  1511. \begingroup
  1512. \catcode`\%=12 \catcode`\#=14
  1513. \gdef\processLineX{#
  1514.   \ifx%\nextToken
  1515.     \let\doNext\processLineXX
  1516.   \else
  1517.     \closeOption
  1518.     \ifOff
  1519.       \let\doNext\removeLine
  1520.     \else
  1521.       \let\doNext\copyLine
  1522.     \fi
  1523.   \fi
  1524.   \doNext}
  1525. \endgroup
  1526. %    \end{macrocode}
  1527. % \end{macro}
  1528. % \begin{macro}{\processLineXX}
  1529. %    The macro \verb=\processLineXX= simply peeks at the next token and
  1530. %    calls \verb=\processLineXXX= to do whatever is necessary.
  1531. %    \begin{macrocode}
  1532. \def\processLineXX#1{%
  1533.   \futurelet\nextToken\processLineXXX}
  1534. %    \end{macrocode}
  1535. % \end{macro}
  1536. % \begin{macro}{\processLineXXX}
  1537. %    This macro is also defined within a group, like the macro
  1538. %    \verb=\processLineX=, because it also has to check if the next
  1539. %    token in the input stream is a `{\tt\%}' character.
  1540. %    If the second token in the current line happens to be a `{\tt\%}',
  1541. %    a \meta{MetaComment} has been found. This has to be copied in its
  1542. %    entirety to the output.
  1543. %    Another possible second character is `{\tt<}', which introduces
  1544. %    a guard expression. The processing of such an expression is
  1545. %    started by calling \verb=\checkOption=.
  1546. %    When the token was neither a `{\tt\%}' nor a `{\tt<}', the line
  1547. %    contains a normal comment that has to be removed. In that case
  1548. %    the current option is closed.  The execution of the macro
  1549. %    \verb=\doNext= will have the desired effect.  Note that the group
  1550. %    is closed, so that all characters will have the category code
  1551. %    that was in effect when the group was started.
  1552. %    \begin{macrocode}
  1553. \begingroup
  1554. \catcode`\%=12 \catcode`\#=14
  1555. \gdef\processLineXXX{#
  1556.   \ifx%\nextToken \let\doNext\putMetaComment \else
  1557.   \ifx<\nextToken \let\doNext\checkOption    \else
  1558.              \closeOption
  1559.              \let\doNext\removeComment  \fi\fi
  1560.   \doNext}
  1561. \endgroup
  1562. %    \end{macrocode}
  1563. % \end{macro}
  1564. %  \subsection{The handling of options}
  1565. % \begin{macro}{\checkOption}
  1566. %    When the macros that process a line have found that the line
  1567. %    starts with `{\tt\%<}', a guard line has been encountered. The
  1568. %    first character of a guard can be an asterisk ({\tt*}), a slash
  1569. %    ({\tt/}) a plus ({\tt+}), a minus ({\tt-}) or any other character
  1570. %    that can be found in an option name. This means that we have to
  1571. %    peek at the next token and call \verb=\checkOptionsX= to decide
  1572. %    what kind of guard we have. Note that the way that
  1573. %    \verb=\checkOption= is defined, means it removes the `{\tt<}'
  1574. %    from the input stream.
  1575. %    \begin{macrocode}
  1576. \def\checkOption<{%
  1577.   \futurelet\nextToken\checkOptionsX}
  1578. %    \end{macrocode}
  1579. % \end{macro}
  1580. % \begin{macro}{\checkOptionsX}
  1581. %    The macro \verb=\checkOptionsX= compares the contents of
  1582. %    \verb=\nextToken= with the four possible leading characters and
  1583. %    decides what to do. When the switch \verb=\ifOff= is \meta{true},
  1584. %    the current line will simply be removed.
  1585. %    \begin{macrocode}
  1586. \def\checkOptionsX{%
  1587.   \ifx*\nextToken \let\doNext\starOption  \else
  1588.   \ifx/\nextToken \let\doNext\slashOption \else
  1589.   \ifOff          \let\doNext\removeLine  \else
  1590.   \ifx+\nextToken \let\doNext\plusOption  \else
  1591.   \ifx-\nextToken \let\doNext\minusOption \else
  1592.                   \let\doNext\doOption    \fi\fi\fi\fi\fi
  1593.   \doNext}
  1594. %    \end{macrocode}
  1595. % \end{macro}
  1596. % \begin{macro}{\closeOption}
  1597. %    The macro \verb=\closeOption= is used to `close' options. This
  1598. %    means nothing more than writing a `{\tt>}' on the terminal when
  1599. %    necessary.
  1600. %    If \verb=\lastOption= is \verb=\empty= nothing has to be done
  1601. %    because no option has started since the last one was closed. In
  1602. %    the other case, the `{\tt>}' is written on the terminal if
  1603. %    messages are enabled.  Also, the \verb=\lastOption= is made
  1604. %    \verb=\empty=.
  1605. %    \begin{macrocode}
  1606. \def\closeOption{%
  1607.   \ifx\lastOption\empty\else
  1608.     \maybeMsg{>}\let\lastOption\empty\fi}
  1609. %    \end{macrocode}
  1610. % \end{macro}
  1611. % \begin{macro}{\doOption}
  1612. %    When no guard modifier is found by \verb=\checkOptionsX=, the
  1613. %    macro \verb=\doOption= is called.  It calls \verb=\testOption=
  1614. %    with an empty first argument to evaluate the boolean expression.
  1615. %    The result of this evaluation is stored in
  1616. %    \verb=\ExpressionValue=. This guard only affects the current
  1617. %    line, so depending on the result of the test
  1618. %    \verb=\if\ExpressionValue=, the current line is either copied to
  1619. %    the output stream or removed.
  1620. %    \begin{macrocode}
  1621. \def\doOption#1>{%
  1622.   \testOption{}{#1}%
  1623.   \if\ExpressionValue \expandafter\copyLine
  1624.   \else         \expandafter\removeLine \fi}
  1625. %    \end{macrocode}
  1626. % \end{macro}
  1627. % \begin{macro}{\plusOption}
  1628. %    When a `{\tt+}' is found as a guard modifier, \verb=\plusOption=
  1629. %    is called. This macro is very similar to \verb=\doOption=, the only
  1630. %    difference being that the `{\tt+}' is now passed as the first
  1631. %    argument to \verb=\testOption=.
  1632. %    \begin{macrocode}
  1633. \def\plusOption+#1>{%
  1634.   \testOption+{#1}%
  1635.   \if\ExpressionValue \expandafter\copyLine
  1636.   \else         \expandafter\removeLine \fi}
  1637. %    \end{macrocode}
  1638. % \end{macro}
  1639. % \begin{macro}{\minusOption}
  1640. %    When a `{\tt-}' is found as a guard modifier, \verb=\minusOption=
  1641. %    is called. This macro is very similar to \verb=\plusOption=, the
  1642. %    difference is that \verb=\removeLine= and \verb=\copyLine= have
  1643. %    been interchanged.
  1644. %    \begin{macrocode}
  1645. \def\minusOption-#1>{%
  1646.   \testOption-{#1}%
  1647.   \if\ExpressionValue \expandafter\removeLine
  1648.   \else         \expandafter\copyLine \fi}
  1649. %    \end{macrocode}
  1650. % \end{macro}
  1651. % \begin{macro}{\starOption}
  1652. %    When a `{\tt*}' is found as a guard modifier, \verb=\starOption=
  1653. %    is called. In this case a block of code will be included in the
  1654. %    output on the condition that the guard expression evaluates to
  1655. %    \meta{true}.
  1656. %    \begin{macrocode}
  1657. \def\starOption*#1>{%
  1658. %    \end{macrocode}
  1659. %    First we close any pending option and optionally write
  1660. %    a message to the terminal to indicate that a new option starts
  1661. %    here.
  1662. %    \begin{macrocode}
  1663.   \closeOption
  1664.   \maybeMsg{<*#1}%
  1665. %    \end{macrocode}
  1666. %    Then we push the current contents of \verb=\blockHead= on the
  1667. %    stack of blocks, \verb=\guardStack= and increment  the counter
  1668. %    \verb=\blockLevel= to indicate that we are now one level of
  1669. %    nesting deeper.
  1670. % \changes{2.0k}{92/04/06}{Use new stack mechanism}
  1671. % \changes{2.0k}{92/04/09}{The macro that holds the guard needs to be
  1672. %    expanded}
  1673. %    \begin{macrocode}
  1674.   \expandafter\push\expandafter\guardStack\expandafter{\blockHead}%
  1675.   \advance\blockLevel\@ne
  1676. %    \end{macrocode}
  1677. %    The guard for this block of code is now stored in
  1678. %    \verb=\blockHead=.
  1679. %    \begin{macrocode}
  1680.   \def\blockHead{#1}%
  1681. %    \end{macrocode}
  1682. %    If this block of code occurs inside another block of code that is
  1683. %    {\em not\/} included in the output, we increment the counter
  1684. %    |\offLevel|. In that case the guard expression will not be
  1685. %    evaluated, because a block inside another block that is excluded
  1686. %    from the output will also be excluded, regardless of the
  1687. %    evaluation of its guard.
  1688. %    \begin{macrocode}
  1689.   \ifOff
  1690.     \advance\offLevel\@ne
  1691. %    \end{macrocode}
  1692. %    When the switch \verb=\ifOff= has the value \meta{false}, we have
  1693. %    to evaluate the guard expression. This is done by calling
  1694. %    |\Evaluate|. That macro leaves the result in |\ExpressionValue|.
  1695. %    If the result turns out to be \meta{false}, we start an `Off'
  1696. %    section by calling \verb=\Offstart=.
  1697. %    \begin{macrocode}
  1698.   \else
  1699.     \Evaluate{#1}%
  1700.     \if\ExpressionValue\else\OffStart\fi
  1701.   \fi
  1702. %    \end{macrocode}
  1703. %    The current line always has to be removed, because it only contains
  1704. %    the guard and possibly a comment.
  1705. %    \begin{macrocode}
  1706.   \removeLine}
  1707. %    \end{macrocode}
  1708. % \end{macro}
  1709. % \begin{macro}{\slashOption}
  1710. %    The macro \verb=\slashOption= is the counter part to
  1711. %    \verb=\starOption=.  It indicates the end of a block of
  1712. %    conditonally included code.  We store the argument in the
  1713. %    temporary control sequence \verb=\tmp=.
  1714. %    \begin{macrocode}
  1715. \def\slashOption/#1>{%
  1716.   \def\tmp{#1}%
  1717. %    \end{macrocode}
  1718. %    When the counter \verb=\blockLevel= has a value less than $1$,
  1719. %    this `end-of-block' line has no corresponding `start-of-block'.
  1720. %    Therefore we signal an error and ignore this end of block.
  1721. %    \begin{macrocode}
  1722.   \ifnum\blockLevel<\@ne
  1723.     \errmessage{Spurious end block </\tmp> ignored}%
  1724. %    \end{macrocode}
  1725. %    Next we compare the contents of \verb=\tmp= with the contents
  1726. %    of \verb=\blockHead=. The latter macro contains the last guard for
  1727. %    a block of code that was encounterd. If the contents match, we
  1728. %    pop the previous guard from the stack.
  1729. %    \changes{2.0k}{92/04/06}{Use new stack mechanism}
  1730. %    \begin{macrocode}
  1731.   \else
  1732.     \ifx\tmp\blockHead
  1733.       \pop\guardStack\blockHead
  1734. %    \end{macrocode}
  1735. %    When the contents of the two macros don't match something is
  1736. %    amiss. We signal this to the user, but accept the `end-of-block'.
  1737. %\note{Is this the desired behaviour??}
  1738. %    \begin{macrocode}
  1739.     \else
  1740.       \errmessage{Found </\tmp> instead of <*\blockHead>}%
  1741.     \fi
  1742. %    \end{macrocode}
  1743. %    When the end of a block of optionally included code is encountered
  1744. %    we optionally signal this on the terminal and decrement the counter
  1745. %    \verb=\offLevel=.
  1746. %    \begin{macrocode}
  1747.     \maybeMsg{>}%
  1748.     \advance\blockLevel\m@ne
  1749. %    \end{macrocode}
  1750. %    The last check that has to be made is for the value of the switch
  1751. %    \verb=\ifOff=. If it is \meta{true} we call \verb=\Offend= to
  1752. %    take the appropriate actions. Finally we remove the current line.
  1753. %    \begin{macrocode}
  1754.     \ifOff\OffEnd\fi
  1755.   \fi
  1756.   \removeLine}
  1757. %    \end{macrocode}
  1758. % \end{macro}
  1759. % \begin{macro}{\testOption}
  1760. %    The macro \verb=\testOption= is used by the macros that process
  1761. %    the one line guards. First it checks if the guard expression
  1762. %    is present. To accomplish that, it stores the second argument
  1763. %    in a temporary control sequence.
  1764. %    \begin{macrocode}
  1765. \def\testOption#1#2{%
  1766.   \def\tmp{#2}%
  1767. %    \end{macrocode}
  1768. %    When the macro \verb=\tmp= is empty, something is missing.
  1769. %    We signal this to the user and use a dummy guard.
  1770. %    \begin{macrocode}
  1771.   \ifx\tmp\empty
  1772.     \errmessage{Missing option expression!}%
  1773.     \def\tmp{MISSING OPTION}%
  1774. %    \end{macrocode}
  1775. %    When the guard is present we store a `{\tt<}', the guard modifier
  1776. %    and the guard in \verb=\tmp= for future use.
  1777. %    \begin{macrocode}
  1778.   \else
  1779.     \def\tmp{<#1#2}%
  1780.   \fi
  1781. %    \end{macrocode}
  1782. %    The complete guard is now stored in \verb=\tmp=. We use it to
  1783. %    compare with the last guard encountered. If they are the same,
  1784. %    there is nothing more to do.
  1785. %    \begin{macrocode}
  1786.   \ifx\tmp\lastOption
  1787. %    \end{macrocode}
  1788. %    If they are {\em not\/} the same the current line belongs to a
  1789. %    different option than the last line with a guard that has been
  1790. %    processed.  Therefore we close a possibly pending option and make
  1791. %    \verb=\lastOption= point to the contents of \verb=\tmp=.
  1792. %    \begin{macrocode}
  1793.   \else
  1794.     \closeOption
  1795.     \let\lastOption\tmp
  1796. %    \end{macrocode}
  1797. %    Then we optionally signal the start of a new option on the
  1798. %    terminal and evaluate the guard expression.
  1799. %    \begin{macrocode}
  1800.     \maybeMsg{\lastOption}%
  1801.     \Evaluate{#2}%
  1802.   \fi}
  1803. %    \end{macrocode}
  1804. % \end{macro}
  1805. %    \subsection{Batchfile commands}
  1806. % \begin{macro}{\generateFile}
  1807. %    The macro \verb=\generateFile= can be used in batch files to
  1808. %    instruct the \ds{} program to generate an output file from
  1809. %    possibly multiple input files. The first argument is the file to
  1810. %    produce, the second argument indicates if the user has to be
  1811. %    consulted before an existing file is overwritten. The third
  1812. %    argument contains the list of input files. Each entry should have
  1813. %    the format
  1814. %    \verb=\from{=\meta{filename.ext}\verb=}{=\meta{options}\verb=}=.
  1815. %    The macro starts by displaying a message on the terminal to
  1816. %    indicate which file is going to be made.  The switch
  1817. %    \verb=\ifGenerate= is initially set to \meta{true}.
  1818. % \changes{2.0e}{91/06/01}{changed interface to {\tt\bsl generatefileX}}
  1819. % \changes{2.0e}{91/06/01}{Added pre- and postamble support}
  1820. %    \begin{macrocode}
  1821. \def\generateFile#1#2#3{{%
  1822.   \Msg{^^JGenerating file \WriteToDir#1^^J}%
  1823.   \Generatetrue
  1824. %    \end{macrocode}
  1825. %    Next we decide if we have to be careful about overwriting
  1826. %    existing files. If the user specified `{\tt t}' we will ask him
  1827. %    if he wants to overwrite an existing file. If he specified anything
  1828. %    else we simply go ahead.
  1829. %    In order to prevent havoc when \verb=#2= contains garbage or when
  1830. %    it is empty we use a comparison of control sequences instead
  1831. %    of the direct comparison with \verb=\if#2t=.
  1832. %    \begin{macrocode}
  1833.   \def\tmp{#2}\def\t{t}%
  1834.   \ifx\tmp\t
  1835. %    \end{macrocode}
  1836. %    When the second argument to \verb=\generateFile= was `{\tt t}' we
  1837. %    try to open a file with the name of the output file for reading.
  1838. %    If this succeeds the file exists and we ask the user if he wants
  1839. %    to overwrite the file.
  1840. % \changes{2.0p}{92/06/26}{Added `WriteToDir (FMi).}
  1841. %    \begin{macrocode}
  1842.     \immediate\openin\inFile\WriteToDir#1\relax
  1843.     \ifeof\inFile\else
  1844.       \Ask\answer{File \WriteToDir#1 already exists 
  1845.                   \ifx\@empty\WriteToDir somewhere \fi
  1846.                   on the system.^^J% 
  1847.                   Overwrite it%
  1848.                   \ifx\@empty\WriteToDir\space if necessary\fi
  1849.                   ? [y/n]}%
  1850. %    \end{macrocode}
  1851. %    We set the switch \verb=\ifGenerate= according to his answer. We
  1852. %    allow for both ``{\tt y}'' and ``{\tt yes}''.
  1853. %    \begin{macrocode}
  1854.       \ifx\y  \answer \Generatetrue \else
  1855.       \ifx\yes\answer \Generatetrue \else
  1856.                       \Generatefalse\fi\fi\fi
  1857. %    \end{macrocode}
  1858. %    Don't forget to close the file just opened as we want to write
  1859. %    to it.
  1860. %    \begin{macrocode}
  1861.     \immediate\closein\inFile
  1862.   \fi
  1863. %    \end{macrocode}
  1864. %    We store the name of the output file in the macro
  1865. %    \verb=\outFileName= for future use.
  1866. %    \begin{macrocode}
  1867.   \ifGenerate
  1868.     \def\outFileName{#1}%
  1869. %    \end{macrocode}
  1870. %    The macro |\from| will be used for multiple purposes in the
  1871. %    following code.
  1872. %    First |\from| is defined to write a line to the output file,
  1873. %    containing the name of the input file, together with the
  1874. %    options that are included for that file.
  1875. %    \begin{macrocode}
  1876.     \def\from##1##2{\WriteOut{\DoubleperCent ##1 \if!##2!\else
  1877.                               \space (with options: `##2')\fi}}%
  1878. %    \end{macrocode}
  1879. %    The macro \verb=\ReferenceLines= is defined using an \verb=\edef=
  1880. %    instruction. This means that all macros in the replacement text
  1881. %    will be expanded. The third argument to \verb=\generateFile= is
  1882. %    included in the replacement text for \verb=\ReferenceLines=,
  1883. %    while the above definition of \verb=\from= is still valid. Thus,
  1884. %    for each occurence of |\from| in the third argument of
  1885. %    |\generateFile| the current replacement text of |\from| is
  1886. %    included in |\ReferenceLines|.
  1887. %    \begin{macrocode}
  1888.     \edef\ReferenceLines{%
  1889.         \WriteOut{\DoubleperCent ^^J%
  1890.                   \DoubleperCent The original source files were:^^J%
  1891.                   \DoubleperCent }%
  1892.         #3}%
  1893.     \def\from##1##2{\edef\inFileName{\inFileName##1\space}}
  1894.     \def\inFileName{}#3
  1895. %    \end{macrocode}
  1896. %    The macro \verb=\ReferenceLines= will be called by
  1897. %    \verb=\WritePreamble=.  Because it was defined using an expanded
  1898. %    definition we can now safely give \verb=\from= another meaning.
  1899. %    This time it is to define the macros \verb=\inFileName= and
  1900. %    \verb=\Options= to contain its two arguments. These macros are
  1901. %    then used by \verb=\generateFileX=.
  1902. % \changes{2.0f}{91/06/04}{Allow for a control sequence as options
  1903. %    argument}
  1904. %    \begin{macrocode}
  1905.     \def\from##1##2{\def\inFileName{##1}%
  1906.                     \edef\Options{##2}%
  1907.                     \generateFileX}%
  1908. %    \end{macrocode}
  1909. %    Now we can finally open the output file, this time for writing.
  1910. % \changes{2.0q}{92/07/01}{Preceded filename by `WriteToDir}
  1911. %    \begin{macrocode}
  1912.     \immediate\openout\outFile\WriteToDir#1\relax
  1913. %    \end{macrocode}
  1914. %    First we write a preamble to the file,
  1915. %    \begin{macrocode}
  1916.     \WritePreamble
  1917. %    \end{macrocode}
  1918. %    then we execute the commands that are in the third
  1919. %    argument to \verb=\Generatefile=.
  1920. %    \begin{macrocode}
  1921.     #3%
  1922. %    \end{macrocode}
  1923. %    The last action is to write a postamble to the file and close it.
  1924. %    \begin{macrocode}
  1925.     \WritePostamble
  1926.     \immediate\closeout\outFile
  1927.     \let\ReferenceLines\OriginalRefs
  1928.   \else
  1929. %    \end{macrocode}
  1930. %    In case we were not allowed to overwrite an existing file
  1931. %    we inform the user that we are {\em not\/} generating his file.
  1932. %    \begin{macrocode}
  1933.     \Msg{Not generating file #1^^J}%
  1934.   \fi}}
  1935. %    \end{macrocode}
  1936. %  \begin{macro}{\WriteToDir}
  1937. %    The macro |\WriteToDir| is either empty or holds the prefix
  1938. %    necessary to read a file from the current directory. Under UNIX
  1939. %    this is |./| but a lot of other systems addopted this concept. If
  1940. %    we can prefix the
  1941. % \changes{2.0p}{92/06/26}{Macro added (FMi).}
  1942. %    \begin{macrocode}
  1943. \def\WriteToDir{}
  1944. %<+unix>\def\WriteToDir{./}
  1945. %    \end{macrocode}
  1946. %  \end{macro}
  1947. %    To support command files that were written for the first version
  1948. %    of \ds{} the commands |\include| and |\processFile|
  1949. %    are defined here. The use of this interface is not recommended
  1950. %    as it may be removed in a future release of \ds{}.
  1951. % \begin{macro}{\include}
  1952. % \changes{2.0f}{91/06/04}{Macro added} To provide the \ds{} program
  1953. %    with a list of options that should be included in the output the
  1954. %    command \verb=\include{=\meta{Options}\verb=}= can be used. This
  1955. %    macro is meant to be used in conjunction with the
  1956. %    \verb=\processFile= command.
  1957. %    \begin{macrocode}
  1958. \def\include#1{\def\Options{#1}}
  1959. %    \end{macrocode}
  1960. % \end{macro}
  1961. % \begin{macro}{\processFile}
  1962. % \changes{2.0f}{91/06/04}{Supply {\tt\bsl generateFile} with
  1963. %                          {\tt\bsl Options}}
  1964. %\DeleteShortVerb\|
  1965. %    The macro
  1966. %    \verb=\processFile{=\meta{filename}\verb=}{=\meta{inext}\verb=}{=%
  1967. %\unskip\meta{outext}\verb=}{=\meta{t{\fontshape{n}\tt|}f}\verb=}=
  1968. %    can be used when a single input file is used to produce
  1969. %    a single output file. The macro is also used in the interactive
  1970. %    mode of the \ds{} program.
  1971. %\MakeShortVerb\|
  1972. %    The arguments \meta{inext} and \meta{outext} denote the
  1973. %    extensions of the input and output files respectively. The fourth
  1974. %    argument can be used to specify if an existing file should be
  1975. %    overwritten without asking. If \meta{t} is specified the program
  1976. %    will ask for permission before overwriting an existing file.
  1977. %    This macro is defined using the more generic macro |\generateFile|.
  1978. %    \begin{macrocode}
  1979. \def\processFile#1#2#3#4{%
  1980.   \generateFile{#1.#3}{#4}{\from{#1.#2}{\Options}}}
  1981. %    \end{macrocode}
  1982. % \end{macro}
  1983. % \begin{macro}{\processfile}
  1984. % \begin{macro}{\generatefile}
  1985. % \changes{2.0m}{91/04/23}{Now issue a warning when {\tt\bsl
  1986. %    processfile} or {\tt\bsl generatefile} are used} An earlier
  1987. %    version of \ds{} used the commands |\processfile| and
  1988. %    |\generatefile| instead of the commands as they are defined in
  1989. %    this version. To remain upwards compatible, we still provide
  1990. %    these commands, but issue a warning when they are used.
  1991. %    \begin{macrocode}
  1992. \def\processfile{\Msg{%
  1993.     ^^Jplease use \string\processFile\space instead of 
  1994.        \string\processfile!^^J}%
  1995.     \processFile}
  1996. \def\generatefile{\Msg{%
  1997.     ^^Jplease use \string\generateFile\space instead of 
  1998.       \string\generatefile!^^J}%
  1999.     \generateFile}
  2000. %    \end{macrocode}
  2001. % \end{macro}
  2002. % \end{macro}
  2003. % \begin{macro}{\generateFileX}
  2004. % \changes{2.0f}{91/06/04}{Added check for lines with {\tt\bsl
  2005. %    endinput}} This macro is called by |\generateFile| for each
  2006. %    occurence in its third argument of the control sequence |\from|.
  2007. %    A line is displayed on the terminal, telling the user what we are
  2008. %    about to do.
  2009. %    \begin{macrocode}
  2010. \def\generateFileX{{%
  2011.   \Msg{Processing File \inFileName
  2012.        \ifx\Options\empty\else\space(\Options)\fi
  2013.        \space -> \outFileName^^J}%
  2014. %    \end{macrocode}
  2015. %    Then we try to open the input file. If this doesn't succeed, we
  2016. %    tell the user so and nothing else happens.
  2017. %    \begin{macrocode}
  2018.   \immediate\openin\inFile\inFileName\relax
  2019.   \ifeof\inFile
  2020.     \errmessage{Cannnot find file \inFileName}%
  2021.   \else
  2022. %    \end{macrocode}
  2023. %    When the input file was successfully opened, we change the category
  2024. %    code of a lot of characters to \meta{other} and make sure that
  2025. %    no extra spaces appear in the lines read by setting the
  2026. %    |\endlinechar| to $-1$.
  2027. %    \begin{macrocode}
  2028.     \makeOther\ \makeOther\\\makeOther\$%
  2029.     \makeOther\#\makeOther\^\makeOther\^^K%
  2030.     \makeOther\_\makeOther\^^A\makeOther\%%
  2031.     \makeOther\~\makeOther\{\makeOther\}\makeOther\&%
  2032.     \endlinechar-1\relax
  2033. %    \end{macrocode}
  2034. %    Then we start a loop to process the lines in the file one by one.
  2035. %    \begin{macrocode}
  2036.     \loop
  2037.       \read\inFile to\inLine
  2038. %    \end{macrocode}
  2039. %    The first thing we check is whether the current line
  2040. %    contains an |\endinput|. To allow also real |\endinput|
  2041. %    commands in the source file, |\endinput| is only recognized
  2042. %    when it occurs directly at the beginning of a line.
  2043. %    \begin{macrocode}
  2044.       \ifx\inLine\Endinput
  2045. %    \end{macrocode}
  2046. %    In this case we output a message to inform the programmer (in
  2047. %    case this was a mistake) and end the loop immediately by setting
  2048. %    \verb=Continue= to \meta{false}. Note that \verb=\endinput= is
  2049. %    not placed into the output file. This is important in cases where
  2050. %    the output file is generated from several {\tt doc} files.
  2051. %    \begin{macrocode}
  2052.         \Msg{File \inFileName\space ended by \string\endinput.}%
  2053.         \Continuefalse
  2054.       \else
  2055. %    \end{macrocode}
  2056. % \changes{2.0j}{92/03/03}{First check for end of file before check for
  2057. %    empty lines} When the end of the file is found we have to
  2058. %    interrupt the loop.
  2059. %    \begin{macrocode}
  2060.        \ifeof\inFile
  2061.          \Continuefalse
  2062. %    \end{macrocode}
  2063. % \changes{2.0i}{91/06/27}{Added check for consecutive empty lines}
  2064. %    If the file did not end we check if the input line is empty.
  2065. %    If it is, the counter \verb=\emptyLines= is incremented.
  2066. %    \begin{macrocode}
  2067.        \else
  2068.          \Continuetrue
  2069.          \ifx\inLine\empty
  2070.             \advance\emptyLines\@ne
  2071.           \else
  2072.             \emptyLines\z@
  2073.           \fi
  2074. %    \end{macrocode}
  2075. %    When the number of empty lines seen so far exceeds 1, we skip them.
  2076. %    If it doesn't, the expansion of |\inLine| is fed to |\processLine|
  2077. %    with |\endLine| appended to indicate the end of the line.
  2078. %    \begin{macrocode}
  2079.           \ifnum \emptyLines<2
  2080.             \expandafter\processLine\inLine\endLine
  2081.           \else
  2082.             \maybeMsg{/}%
  2083.           \fi
  2084.        \fi
  2085.       \fi
  2086. %    \end{macrocode}
  2087. %    When the processing of the line is finished, we check if there is
  2088. %    more to do, in which case we repeat the loop.
  2089. %    \begin{macrocode}
  2090.     \ifContinue
  2091.     \repeat
  2092. %    \end{macrocode}
  2093. %    Any option that was not properly `closed' is closed now and the
  2094. %    input file is closed.
  2095. %    \begin{macrocode}
  2096.     \closeOption
  2097.     \immediate\closein\inFile
  2098. %    \end{macrocode}
  2099. %    If the user was interested in statistics, we inform him of the
  2100. %    number of lines processed, the number of comments that were
  2101. %    either removed or passed and the number of codelines that were
  2102. %    written to the output file. Also the totals are updated.
  2103. %    \begin{macrocode}
  2104. %<*stats>
  2105.     \Msg{Lines \space processed: \the\processedLines^^J%
  2106.          Comments removed: \the\commentsRemoved^^J%
  2107.          Comments \space passed: \the\commentsPassed^^J%
  2108.          Codelines passed: \the\codeLinesPassed^^J}%
  2109.       \global\advance\TotalprocessedLines  by \processedLines
  2110.       \global\advance\TotalcommentsRemoved by \commentsRemoved
  2111.       \global\advance\TotalcommentsPassed  by \commentsPassed
  2112.       \global\advance\TotalcodeLinesPassed by \codeLinesPassed
  2113.       \global\advance\NumberOfFiles by \@ne
  2114. %</stats>
  2115.     \fi}}
  2116. %    \end{macrocode}
  2117. % \end{macro}
  2118. % \end{macro}
  2119. % \begin{macro}{\WritePreamble}
  2120. % \changes{2.0e}{91/06/01}{Macro added.}
  2121. %    If there is no \verb=\preamble= command in the batch file, or
  2122. %    the \ds{} program is used in interactive mode a
  2123. %    default preamble will be written to the output file. All
  2124. %    lines in this preamble are preceded by two percent characters
  2125. %    to prevent them from being removed from the file by the \ds{}
  2126. %    program.
  2127. %    First a couple of lines, stating what file it is and how it was
  2128. %    created.
  2129. %    \begin{macrocode}
  2130. \def\WritePreamble{%
  2131.     \WriteOut{%
  2132.         \DoubleperCent ^^J%
  2133.         \DoubleperCent This is file `\outFileName', generated %
  2134.                         on <\the\year/\the\month/\the\day> ^^J%
  2135.         \DoubleperCent with the docstrip utility (\fileversion).%
  2136.              }%
  2137. %    \end{macrocode}
  2138. %    Then the |\ReferenceLines| that tell from what source file(s) the
  2139. %    stripped file was created.
  2140. %    \begin{macrocode}
  2141.     \ReferenceLines
  2142. %    \end{macrocode}
  2143. %    Then, a statement that this file should {\em not\/} be distributed
  2144. %    on its own.
  2145. %    \begin{macrocode}
  2146.     \WriteOut{%
  2147.         \DoubleperCent ^^J%
  2148.         \DoubleperCent IMPORTANT NOTICE:^^J%
  2149.         \DoubleperCent You are not allowed to distribute this file.^^J%
  2150.         \DoubleperCent For distribution of the original source see^^J%
  2151.         \DoubleperCent the copyright notice in the file \inFileName.^^J%
  2152.         \DoubleperCent }}
  2153. %    \end{macrocode}
  2154. % \end{macro}
  2155. % \begin{macro}{\OriginalRefs}
  2156. % \changes{2.0e}{91/06/01}{Macro added.}
  2157. %    The macro \verb=\OriginalRefs= can be used to include information
  2158. %    in the output file about the documented source files it was
  2159. %    created from.
  2160. %    \begin{macrocode}
  2161. \def\OriginalRefs{%
  2162.     \WriteOut{\DoubleperCent }%
  2163.     \WriteOut{\DoubleperCent The original source file was 
  2164.               `\inFileName'.}%
  2165.     \ifx\Options\empty\else
  2166.         \WriteOut{\DoubleperCent Included options: `\Options'.}\fi
  2167.     \WriteOut{\DoubleperCent }}
  2168. %    \end{macrocode}
  2169. % \end{macro}
  2170. % \begin{macro}{\ReferenceLines}
  2171. % \changes{2.0e}{91/06/01}{Macro added.} The macro
  2172. %    \verb=\ReferenceLines= is used by the macro \verb=\WritePreamble=
  2173. %    to include some information on the original source files in the
  2174. %    output file. When the user does not supply a preamble, a default
  2175. %    preamble is used, so also a default value for
  2176. %    \verb=\ReferenceLines= has to be supplied. The macro
  2177. %    \verb=\OriginalRefs= supplies such a default.
  2178. %    \begin{macrocode}
  2179. \let\ReferenceLines\OriginalRefs
  2180. %    \end{macrocode}
  2181. % \end{macro}
  2182. % \begin{macro}{\WritePostamble}
  2183. % \changes{2.0e}{91/06/01}{Macro added.}
  2184. %    The default definition of \verb=\WritePostamble= is to write
  2185. %    a line containing \verb=\endinput= to the output file. The
  2186. %    last line written identifies the file again.
  2187. %    \begin{macrocode}
  2188. \def\WritePostamble{%
  2189.     \WriteOut{\string\endinput}%
  2190.     \WriteOut{\DoubleperCent ^^J%
  2191.               \DoubleperCent End of file `\outFileName'.}}
  2192. %    \end{macrocode}
  2193. % \end{macro}
  2194. % \begin{macro}{\preamble}
  2195. % \changes{2.0e}{91/06/01}{Macro added.} When a batch file is used the
  2196. %    user can specify a preamble of his own that will be written to
  2197. %    each file that is created. This can be useful to include an extra
  2198. %    copyright notice in the stripped version of a file.  Also a
  2199. %    warning that both versions of a file should {\em always\/} be
  2200. %    distributed together could be written to a stripped file by
  2201. %    including it in such a preamble.
  2202. %    Every line that is written to \verb=\outFile= that belongs to the
  2203. %    preamble is preceded by two percent characters. This will prevent
  2204. %    \ds{} from stripping these lines off the file.
  2205. %    The preamble should be started with the macro \verb=\preamble=;
  2206. %    it is ended by \verb=\endpreamble=. All processing is done within
  2207. %    a group in order to be able to locally redefine some macros.
  2208. %    \begin{macrocode}
  2209. \def\preamble{\begingroup
  2210. %    \end{macrocode}
  2211. %    If the preamble contains an empty line this will end up in
  2212. %    the macro \verb=\batchLine= as \verb=\par=. To be able to
  2213. %    recognize a \verb=\par= we define \verb=\tmp= to contain
  2214. %    \verb=\par=. The macro \verb=\Endpreamble= is defined to contain
  2215. %    \verb=\endpreamble=, which ends the processing of preamble lines.
  2216. %    \begin{macrocode}
  2217.     \def\tmp{\par}%
  2218.     \def\Endpreamble{\endpreamble}%
  2219. %    \end{macrocode}
  2220. %    The preamble lines will be read inside a \verb=\loop=. When
  2221. %    a line is found that contains \verb=\endpreamble= the processing
  2222. %    has to stop. This is controlled by the switch \verb=\ifContinue=.
  2223. %    We initialize it to \meta{true}.
  2224. %    \begin{macrocode}
  2225.     \Continuetrue
  2226. %    \end{macrocode}
  2227. %    The macro \verb=\WritePreamble= will be defined to contain
  2228. %    commands to write all preamble lines to \verb=\outFile=. We start
  2229. %    it off with a couple of lines identifying the file. More lines
  2230. %    will be added as processing continues, therefore the macros
  2231. %    \verb=\inFileName= and \verb=\outFileName= are \verb=\let= to
  2232. %    \verb=\relax=. If this was not done their contents would now be
  2233. %    hard-coded in \verb=\WritePreamble=, which is {\em not\/} what we
  2234. %    want.
  2235. % \changes{2.0h}{91/06/19}{Removed opening of output file as a side
  2236. %    effect.}
  2237. %    \begin{macrocode}
  2238.     \let\inFileName\relax
  2239.     \let\outFileName\relax
  2240.     \let\ReferenceLines\relax
  2241.     \gdef\WritePreamble{%
  2242.         \WriteOut{\DoubleperCent ^^J%
  2243.                   \DoubleperCent This is file `\outFileName',
  2244.                                  generated ^^J%
  2245.                   \DoubleperCent on <\the\year/\the\month/\the\day> with
  2246.                                  the docstrip utility (\fileversion).}%
  2247.         \ReferenceLines}%
  2248. %    \end{macrocode}
  2249. %    Now  each line in the preamble has to be added to
  2250. %    \verb=\WritePreamble=, therfore we start a \verb=\loop= to
  2251. %    \verb=\read= the lines. The control sequence \verb=\batchLine=
  2252. %    is used to store each line.
  2253. %    \begin{macrocode}
  2254.     \loop
  2255.         \read\batchFile to \batchLine
  2256. %    \end{macrocode}
  2257. %    We check to see if the end of the preamble has been found. In that
  2258. %    case the \verb=\loop= has to come to an end, so we set the switch
  2259. %    \verb=\ifContinue= to \meta{false}.
  2260. %    \begin{macrocode}
  2261.         \ifx\batchLine\Endpreamble \Continuefalse
  2262.         \else
  2263. %    \end{macrocode}
  2264. %    If an extra line has been read we add the appropriate
  2265. %    instructions to \verb=\WritePreamble= using \verb=\xdef= (which
  2266. %    does a global expanded definition). If the \verb=\batchLine= was
  2267. %    empty, we write just the two percent characters; otherwise the
  2268. %    complete line is written, preceded by the two percent characters.
  2269. %    \begin{macrocode}
  2270.             \xdef\WritePreamble{%
  2271.                 \WritePreamble
  2272.                 \WriteOut{\DoubleperCent 
  2273.                           \ifx\batchLine\tmp\else\batchLine\fi}}%
  2274.         \fi
  2275. %    \end{macrocode}
  2276. %    The setting of the switch \verb=\ifContinue= will decide if the
  2277. %    \verb=\loop= continues. If we end the \verb=\loop=, we also have to
  2278. %    close the group.
  2279. %    \begin{macrocode}
  2280.     \ifContinue\repeat
  2281.     \endgroup}
  2282. %    \end{macrocode}
  2283. % \end{macro}
  2284. % \begin{macro}{\postamble}
  2285. % \changes{2.0e}{91/06/01}{Macro added.} Just as a preamble can be
  2286. %    specified in a batch file, the same can be done for a {\em
  2287. %    post\/}amble.
  2288. %    The definition for \verb=\postamble= is very much like the one for
  2289. %    \verb=\preamble=; the processing takes place inside a group and
  2290. %    the switch \verb=\ifContinue= is used to control the \verb=\loop=.
  2291. %    \begin{macrocode}
  2292. \def\postamble{\begingroup
  2293.     \Continuetrue
  2294. %    \end{macrocode}
  2295. %    The end of the postamble is indicated by \verb=\endpostamble= and
  2296. %    the postamble can contain empty lines so we have to be able
  2297. %    to check if \verb=\batchLine= contains a \verb=\par=.
  2298. %    \begin{macrocode}
  2299.     \def\Endpostamble{\endpostamble}%
  2300.     \def\tmp{\par}%
  2301. %    \end{macrocode}
  2302. %    We initially define \verb=\WritePostamble= as an empty macro.
  2303. %    Commands will be added to it as we go along.
  2304. %    \begin{macrocode}
  2305.     \gdef\WritePostamble{}%
  2306. %    \end{macrocode}
  2307. %    We start a loop to read lines from the batch file until
  2308. %    \verb=\postamble= is encountered.
  2309. %    \begin{macrocode}
  2310.     \loop
  2311.         \read\batchFile to \batchLine
  2312.         \ifx\batchLine\Endpostamble \Continuefalse
  2313. %    \end{macrocode}
  2314. %    The line just read will be written to \verb=\outFile=, prepended
  2315. %    with two percent characters. The command to do this is appended
  2316. %    to the definition of \verb=\WritePostamble=.
  2317. %    \begin{macrocode}
  2318.         \else
  2319.             \xdef\WritePostamble{%
  2320.                \WritePostamble
  2321.                \WriteOut{\DoubleperCent 
  2322.                          \ifx\batchLine\tmp\else\batchLine\fi}}%
  2323.         \fi
  2324. %    \end{macrocode}
  2325. %    The setting of the switch \verb=\ifContinue= decides if we have
  2326. %    to stop the \verb=\loop=.
  2327. %    \begin{macrocode}
  2328.     \ifContinue\repeat
  2329.     \endgroup}
  2330. %    \end{macrocode}
  2331. % \end{macro}
  2332. %    \subsection{Interaction with the user}
  2333. % \begin{macro}{\processbatchFile}
  2334. % \changes{2.0f}{91/06/04}{Macro added.}
  2335. %    When \ds{} is run it always tries to use a batch file.
  2336. %    For this purpose it calls the macro |\processbatchFile|. The first
  2337. %    thing this macro does, is check wether the user has defined the
  2338. %    control sequence |\batchfile|. If he did, it should contain the
  2339. %    name of the file to process. If he didn't a default name is tried.
  2340. %    Whether or not the default batch file is used is remembered by
  2341. %    setting the switch |\ifDefault| to \meta{true} or \meta{false}.
  2342. %    \begin{macrocode}
  2343. \def\processbatchFile{%
  2344.     \ifx\undefined\batchfile
  2345.       \let\batchfile\DefaultbatchFile
  2346.       \Defaulttrue
  2347.     \else
  2348.       \Defaultfalse
  2349.     \fi
  2350. %    \end{macrocode}
  2351. %    Now we try to open the batch file for reading.
  2352. %    \begin{macrocode}
  2353.     \openin\batchFile \batchfile\relax
  2354.     \ifeof\batchFile
  2355. %    \end{macrocode}
  2356. %    If we didn't succeed in opening the file, we assume that it does
  2357. %    not exist. If we tried the default filename, we silently
  2358. %    continue; the \ds{} program will switch to interactive mode in
  2359. %    this case.
  2360. %    \begin{macrocode}
  2361.       \ifDefault
  2362.       \else
  2363. %    \end{macrocode}
  2364. %    If we failed to open the user-supplied file, something is wrong
  2365. %    and we warn him about it. This will also result in a switch to
  2366. %    interactive mode.
  2367. %    \begin{macrocode}
  2368.         \Msg{**************************************************^^J%
  2369.              * Could not find your \string\batchfile=\batchfile^^J%
  2370.              * Try to continue without it^^J%
  2371.              **************************************************}%
  2372.       \fi
  2373.     \else
  2374. %    \end{macrocode}
  2375. %    When we were successful in opening a file, we again have to check
  2376. %    whether it was the default file. In that case we tell the user
  2377. %    we found that file and ask him if he wants to use it.
  2378. %    \begin{macrocode}
  2379.       \ifDefault
  2380.         \Msg{**************************************************^^J%
  2381.              * Batchfile \DefaultbatchFile\space found Use it? (y/n)?}%
  2382.         \Ask\answer{%
  2383.              **************************************************}%
  2384.       \else
  2385. %    \end{macrocode}
  2386. %    When it was the user-supplied file we can safely assume he wants
  2387. %    to use it so we set |\answer| to {\tt y}.
  2388. %    \begin{macrocode}
  2389.         \let\answer\y
  2390.       \fi
  2391. %    \end{macrocode}
  2392. %    At this point we have successfully opened a batch file for
  2393. %    reading.  If the macro |\answer| contains a {\tt y} we can
  2394. %    proceed. We do that by setting the switch |\ifContinue| to true.
  2395. %    When the batch file contains an |\endinput| we shouldn't
  2396. %    continue, so we make it switch |\ifContinue| to \meta{false}.
  2397. %    \begin{macrocode}
  2398.       \ifx\answer\y
  2399.         \Continuetrue
  2400.         \let\endinput\Continuefalse
  2401. %    \end{macrocode}
  2402. %    The contents of the batch file are read in a loop, line by line.
  2403. %    When the end of the file is found processing should stop.
  2404. %    \begin{macrocode}
  2405.         \loop
  2406.           \ifeof\batchFile
  2407.             \Continuefalse
  2408.           \else
  2409. %    \end{macrocode}
  2410. %    A line is read into the macro |\batchLine|, which is subsequently
  2411. %    executed.
  2412. %    \begin{macrocode}
  2413.             \read\batchFile to \batchLine
  2414.             \batchLine
  2415.           \fi
  2416. %    \end{macrocode}
  2417. %    When the execution of |\batchLine| is finished we check the switch
  2418. %    |\ifContinue| to see if have to continue reading.
  2419. %    \begin{macrocode}
  2420.         \ifContinue\repeat
  2421.       \fi
  2422.     \fi}
  2423. %    \end{macrocode}
  2424. % \end{macro}
  2425. % \begin{macro}{\ReportTotals}
  2426. % \changes{2.0g}{91/06/05}{Macro added.} The macro
  2427. %    \verb=\ReportTotals= can be used to report total statistics for
  2428. %    all files processed. This code is only included in the program if
  2429. %    the option {\tt stats} is included.
  2430. %    \begin{macrocode}
  2431. %<*stats>
  2432. \def\ReportTotals{%
  2433.   \ifnum\NumberOfFiles>\@ne
  2434.     \Msg{Overall statistics:^^J%
  2435.          Files \space processed: \the\NumberOfFiles^^J%
  2436.          Lines \space processed: \the\TotalprocessedLines^^J%
  2437.          Comments removed: \the\TotalcommentsRemoved^^J%
  2438.          Comments \space passed: \the\TotalcommentsPassed^^J%
  2439.          Codelines passed: \the\TotalcodeLinesPassed}%
  2440.   \fi}
  2441. %</stats>
  2442. %    \end{macrocode}
  2443. % \end{macro}
  2444. % \begin{macro}{\SetFileNames}
  2445. %    The macro \verb=\SetFileNames= is used when the program runs in
  2446. %    interactive mode and the user was asked to supply extensions and
  2447. %    a list of filenames.
  2448. %    \begin{macrocode}
  2449. \def\SetFileNames{%
  2450.     \edef\inFileName{\MainFileName.\infileext}%
  2451.     \edef\outFileName{\MainFileName.\outfileext}}
  2452. %    \end{macrocode}
  2453. % \end{macro}
  2454. % \begin{macro}{\CheckFileNames}
  2455. %    In interactive mode, the user gets asked for the extensions for
  2456. %    the input and output files. Also the name or names of the input
  2457. %    files (without extension) is asked for. Then the names of the
  2458. %    input and output files are constructed from this information by
  2459. %    |\SetFileNames|. This assumes that the name of the input file is
  2460. %    the same as the name of the output file. But we should not write
  2461. %    to the same file we're reading from so the extensions should
  2462. %    differ.
  2463. %    The macro |\CheckFileNames| makes sure that the output goes to a
  2464. %    different file to the one where the input comes from.
  2465. %    \begin{macrocode}
  2466. \def\CheckFileNames{%
  2467.     \ifx\inFileName\outFileName
  2468. %    \end{macrocode}
  2469. %    If input and output files are the same we signal an error and stop
  2470. %    processing.
  2471. %    \begin{macrocode}
  2472.       \Msg{^^J%
  2473.      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!^^J%
  2474.      ! It is not possible to read from and write to the same file !^^J%
  2475.      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!^^J}%
  2476.       \Continuefalse
  2477.     \else
  2478. %    \end{macrocode}
  2479. %    If they are not the same we check if the input file exists by
  2480. %    trying to open it for reading.
  2481. %    \begin{macrocode}
  2482.       \Continuetrue
  2483.       \immediate\openin\inFile \inFileName\relax
  2484.       \ifeof\inFile
  2485. %    \end{macrocode}
  2486. %    If an end of file was found, the file couldn't be opened, so we
  2487. %    signal an error and stop processing.
  2488. %    \begin{macrocode}
  2489.         \Msg{^^J%
  2490.               !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!^^J%
  2491.               ! Your input file `\inFileName' was not found !^^J%
  2492.               !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!^^J}%
  2493.         \Continuefalse
  2494.       \else
  2495. %    \end{macrocode}
  2496. %    The last check we have to make is if the output file already
  2497. %    exists.  Therefore we try to open it for reading.
  2498. %    As a precaution we first close the input stream.
  2499. % \changes{2.0p}{92/06/26}{Added `WriteToDir (FMi).}
  2500. % \changes{2.0r}{92/08/17}{Use `inFile for reading}
  2501. % \changes{2.0r}{92/08/17}{Moved `closein statements}
  2502. %    \begin{macrocode}
  2503.         \immediate\closein\inFile
  2504.         \immediate\openin\inFile\WriteToDir \outFileName\relax
  2505.         \ifeof\inFile
  2506. %    \end{macrocode}
  2507. %    If this fails, it didn't exist and all is well.
  2508. %    \begin{macrocode}
  2509.           \Continuetrue
  2510.         \else
  2511. %    \end{macrocode}
  2512. %    If opening of the output file for reading succeeded we have to
  2513. %    ask the user if he wants to overwrite it. We assume he doesn't
  2514. %    want to overwrite it, so the switch |\ifContinue| is initially
  2515. %    set to \meta{false}. Only if he answers the question positively
  2516. %    with `{\tt y}' or `{\tt yes}' we set the switch back to
  2517. %    \meta{true}.
  2518. % \changes{2.0p}{92/06/26}{Changed question about overwriting.}
  2519. %    \begin{macrocode}
  2520.           \Continuefalse
  2521.           \Ask\answer{File \WriteToDir\outFileName\space already 
  2522.                       exists 
  2523.                       \ifx\@empty\WriteToDir somewhere \fi
  2524.                       on the system.^^J% 
  2525.                       Overwrite it%
  2526.                       \ifx\@empty\WriteToDir\space if necessary\fi
  2527.                       ? [y/n]}%
  2528.           \ifx\y  \answer \Continuetrue \else
  2529.           \ifx\yes\answer \Continuetrue \else
  2530.           \fi\fi
  2531.         \fi
  2532. %    \end{macrocode}
  2533. %    All checks have been performed now, so we can close any file that
  2534. %    was opened just for this purpose.
  2535. %    \begin{macrocode}
  2536.       \fi
  2537.     \fi
  2538.     \immediate\closein\inFile}
  2539. %    \end{macrocode}
  2540. % \end{macro}
  2541. % \begin{macro}{\interactive}
  2542. %    The macro |\interactive| implements the interactive mode of the
  2543. %    \ds{} program. The macro is implemented using the
  2544. %    \meta{while} construction. While the switch |\ifMoreFiles| remains
  2545. %    true, we continue processing.
  2546. %    \begin{macrocode}
  2547. \def\interactive{%
  2548.   \whileswitch\ifMoreFiles\fi%
  2549. %    \end{macrocode}
  2550. %    To keep macro redefinitions local we start a group and ask the
  2551. %    user some questions about what he wants us to do.
  2552. %    \begin{macrocode}
  2553.    {\begingroup
  2554.       \AskQuestions
  2555. %    \end{macrocode}
  2556. %    The names of the files that have to be processed are stored as a
  2557. %    comma-separated list in the macro |\filelist| by |\AskQuestions|.
  2558. %    We use a \meta{for} loop to process the files one by one.
  2559. %    \begin{macrocode}
  2560.       \forlist\MainFileName:=\filelist
  2561.       \do
  2562. %    \end{macrocode}
  2563. %    First the names of the input and output files are constructed
  2564. %    and a check is made if all filename information is correct.
  2565. %    \begin{macrocode}
  2566.         \SetFileNames
  2567.         \CheckFileNames
  2568.         \ifContinue
  2569. %    \end{macrocode}
  2570. %    If everything was well, we can open the output file for writing,
  2571. % \changes{2.0q}{92/07/01}{Preceded filename by `WriteToDir}
  2572. %    \begin{macrocode}
  2573.           \immediate\openout\outFile\WriteToDir\outFileName\relax
  2574. %    \end{macrocode}
  2575. %    write the preamble to it,
  2576. %    \begin{macrocode}
  2577.           \WritePreamble
  2578. %    \end{macrocode}
  2579. %    process the input file,
  2580. %    \begin{macrocode}
  2581.           \generateFileX
  2582. %    \end{macrocode}
  2583. %    write a postamble
  2584. %    \begin{macrocode}
  2585.           \WritePostamble
  2586. %    \end{macrocode}
  2587. %    and close the output file again.
  2588. %    \begin{macrocode}
  2589.           \immediate\closeout\outFile
  2590.         \fi%
  2591. %    \end{macrocode}
  2592. %    This process is repeated until |\filelist| is exhausted.
  2593. %    \begin{macrocode}
  2594.       \od
  2595.     \endgroup
  2596. %    \end{macrocode}
  2597. %    Maybe the user wants more files to be processed, possibly with
  2598. %    another set of options, so we give him the opportunity.
  2599. %    \begin{macrocode}
  2600.     \Ask\answer{More files to process (y/n)?}%
  2601.     \ifx\y  \answer\MoreFilestrue \else
  2602.     \ifx\yes\answer\MoreFilestrue \else
  2603. %    \end{macrocode}
  2604. %    If he didn't want to process any more files, the switch
  2605. %    |\ifMoreFiles| is set to \meta{false} in order to interrupt the
  2606. %    \meta{while} loop.
  2607. %    \begin{macrocode}
  2608.                    \MoreFilesfalse\fi\fi
  2609.    }}
  2610. %    \end{macrocode}
  2611. % \end{macro}
  2612. % \begin{macro}{\AskQuestions}
  2613. % \changes{2.0e}{91/06/01}{Macro added.}
  2614. %    The macro |\AskQuestions| is called by |\interactive| to get
  2615. %    some information from the user concerning the files that need
  2616. %    to be processed.
  2617. %    \begin{macrocode}
  2618. \def\AskQuestions{%
  2619.     \Msg{^^J%
  2620.          ****************************************************}%
  2621. %    \end{macrocode}
  2622. %    We want to know the extension of the input files,
  2623. %    \begin{macrocode}
  2624.     \Ask\infileext{%
  2625.          * First type the extension of your input file(s): \space  *}%
  2626.     \Msg{****************************************************^^J^^J%
  2627.          ****************************************************}%
  2628. %    \end{macrocode}
  2629. %    the extension of the output files,
  2630. %    \begin{macrocode}
  2631.     \Ask\outfileext{%
  2632.          * Now type the extension of your output file(s) \space: *}%
  2633.     \Msg{****************************************************^^J^^J%
  2634.          ****************************************************}%
  2635. %    \end{macrocode}
  2636. %    if options are to be included and
  2637. %    \begin{macrocode}
  2638.     \Ask\Options{%
  2639.        * Now type the name(s) of option(s) to include \space\space: *}%
  2640.     \Msg{****************************************************^^J^^J%
  2641.          ****************************************************^^J%
  2642.        * Finally give the list of input file(s) without \space\space*}%
  2643. %    \end{macrocode}
  2644. %    the name of the input file or a list of names, separated by commas.
  2645. %    \begin{macrocode}
  2646.     \Ask\filelist{%
  2647.          * extension seperated by commas if necessary %
  2648.                                   \space\space\space\space: *}%
  2649.     \Msg{****************************************************^^J}}%
  2650. %    \end{macrocode}
  2651. % \end{macro}
  2652. % \subsection{The main program}
  2653. %    When \TeX\ processes the \ds{} program it displays
  2654. %    a message about the version of the program and its function
  2655. %    on the terminal.
  2656. %    \begin{macrocode}
  2657. \Msg{Utility: `docstrip' \fileversion\space <\filedate>^^J%
  2658.      English documentation <\docdate>}%
  2659. \Msg{^^J%
  2660.      **********************************************************^^J%
  2661.      * This program converts documented macro-files into fast *^^J%
  2662.      * loadable files by stripping off (nearly) all comments! *^^J%
  2663.      **********************************************************^^J}%
  2664. %    \end{macrocode}
  2665. %    First we try to process a batch file.
  2666. %    \begin{macrocode}
  2667. \processbatchFile
  2668. %    \end{macrocode}
  2669. %    When the number of files processed is still zero,
  2670. %    no batch file was specified and the default
  2671. %    batch file was not found, so we try interactive mode.
  2672. %    \begin{macrocode}
  2673.   \ifnum\NumberOfFiles=\z@
  2674.     \interactive
  2675.   \fi
  2676. %    \end{macrocode}
  2677. %    When we're done and statistics are included we provide a statistics
  2678. %    report about the complete run. Then we \verb=\end= the \TeX-run.
  2679. %    \begin{macrocode}
  2680. %<*stats>
  2681. \ReportTotals
  2682. %</stats>
  2683. %</program>
  2684. %    \end{macrocode}
  2685. % \section{Producing the documentation}
  2686. %    We provide a short driver file that can be extracted by the
  2687. %    \ds{} program using the the conditional `{\sf driver}'.  To
  2688. %    allow the use of {\tt docstrip.doc} as a program (e.g., to strip
  2689. %    off its own comments) we don't use a conditional block, but
  2690. %    rather individual `+' guards. Otherwise, {\tt docstrip.doc}
  2691. %    couldn't be run directly through \TeX{} any longer.
  2692. %    \begin{macrocode}
  2693. %<+driver>\documentstyle[doc]{article}
  2694. %<+driver>
  2695. %<+driver>    \EnableCrossrefs
  2696. %<+driver>%    \DisableCrossrefs    % use \DisableCrossrefs if the
  2697. %<+driver>                          % index is ready
  2698. %<+driver>
  2699. %<+driver>   \RecordChanges
  2700. %<+driver>%   \OnlyDescription
  2701. %<+driver>  \CodelineIndex
  2702. %<+driver>
  2703. %<+driver>   \typeout{Expect some Under- and overfull boxes}
  2704. %<+driver>
  2705. %<+driver>\begin{document}
  2706. %<+driver>  \DocInput{docstrip.doc}
  2707. %<+driver>\end{document}
  2708. %    \end{macrocode}
  2709. % \Finale
  2710. \endinput
  2711.